diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-04-30 10:58:23 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-30 10:58:23 +0000 |
commit | 0276ec39a9c3b839c47ce28838a8d5af25fbf598 (patch) | |
tree | 92dfd62b9f3ebf2d73a0bfcaf2b59c513191aead | |
parent | f189f5bbab73b5d04faee4f4d2198f023c9e1522 (diff) | |
parent | b7d95ea80be40c5ee468a5549d84e058a21fc62c (diff) | |
download | gcc-0276ec39a9c3b839c47ce28838a8d5af25fbf598.zip gcc-0276ec39a9c3b839c47ce28838a8d5af25fbf598.tar.gz gcc-0276ec39a9c3b839c47ce28838a8d5af25fbf598.tar.bz2 |
Merge #399
399: Improve error diagnostics in generic argument handling r=philberty a=philberty
When we get GenericBindings such as ::<A=...> this is not allowed
in this context. We can also improve the unexpected number of argument
errors to print the number of expected vs received arguments
An example error message looks like:
```
test.rs:4:12: error: generic item takes at least 1 type arguments but 0 were supplied
1 | struct Foo<A>(A);
| ~
......
4 | let a: Foo = Foo::<i32>(123);
| ^
```
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
Co-authored-by: Marc Poulhiès <dkm@kataplop.net>
21 files changed, 348 insertions, 58 deletions
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h index 7d3a075..b6d3401 100644 --- a/gcc/rust/ast/rust-ast.h +++ b/gcc/rust/ast/rust-ast.h @@ -1232,6 +1232,8 @@ class LifetimeParam : public GenericParam Location locus; public: + Lifetime get_lifetime () const { return lifetime; } + // Returns whether the lifetime param has any lifetime bounds. bool has_lifetime_bounds () const { return !lifetime_bounds.empty (); } diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h index c8542d9..86da203 100644 --- a/gcc/rust/ast/rust-path.h +++ b/gcc/rust/ast/rust-path.h @@ -124,6 +124,10 @@ public: rust_assert (type != nullptr); return type; } + + Location get_locus () const { return locus; } + + Identifier get_identifier () const { return identifier; } }; // Generic arguments allowed in each path expression segment - inline? diff --git a/gcc/rust/hir/rust-ast-lower-base.h b/gcc/rust/hir/rust-ast-lower-base.h index b127ec4..16143d2 100644 --- a/gcc/rust/hir/rust-ast-lower-base.h +++ b/gcc/rust/hir/rust-ast-lower-base.h @@ -291,6 +291,8 @@ protected: HIR::PathExprSegment lower_path_expr_seg (AST::PathExprSegment &s); HIR::GenericArgs lower_generic_args (AST::GenericArgs &args); + + HIR::GenericArgsBinding lower_binding (AST::GenericArgsBinding &binding); }; } // namespace HIR diff --git a/gcc/rust/hir/rust-ast-lower-type.h b/gcc/rust/hir/rust-ast-lower-type.h index 318d126..e647337 100644 --- a/gcc/rust/hir/rust-ast-lower-type.h +++ b/gcc/rust/hir/rust-ast-lower-type.h @@ -265,6 +265,34 @@ public: return resolver.translated; } + void visit (AST::LifetimeParam ¶m) override + { + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, param.get_node_id (), + mappings->get_next_hir_id (crate_num), + mappings->get_next_localdef_id (crate_num)); + HIR::Lifetime::LifetimeType ltt; + + switch (param.get_lifetime ().get_lifetime_type ()) + { + case AST::Lifetime::LifetimeType::NAMED: + ltt = HIR::Lifetime::LifetimeType::NAMED; + break; + case AST::Lifetime::LifetimeType::STATIC: + ltt = HIR::Lifetime::LifetimeType::STATIC; + break; + case AST::Lifetime::LifetimeType::WILDCARD: + ltt = HIR::Lifetime::LifetimeType::WILDCARD; + break; + } + + HIR::Lifetime lt (mapping, ltt, param.get_lifetime ().get_lifetime_name (), + param.get_lifetime ().get_locus ()); + + translated = new HIR::LifetimeParam (mapping, lt, param.get_locus (), + std::vector<Lifetime> ()); + } + void visit (AST::TypeParam ¶m) override { HIR::Attribute outer_attr = HIR::Attribute::create_empty (); diff --git a/gcc/rust/hir/rust-ast-lower.cc b/gcc/rust/hir/rust-ast-lower.cc index 7ba5d32..f1129ab 100644 --- a/gcc/rust/hir/rust-ast-lower.cc +++ b/gcc/rust/hir/rust-ast-lower.cc @@ -314,10 +314,25 @@ ASTLoweringBase::lower_path_expr_seg (AST::PathExprSegment &s) : HIR::GenericArgs::create_empty ()); } +HIR::GenericArgsBinding +ASTLoweringBase::lower_binding (AST::GenericArgsBinding &binding) +{ + HIR::Type *lowered_type + = ASTLoweringType::translate (binding.get_type ().get ()); + return HIR::GenericArgsBinding (binding.get_identifier (), + std::unique_ptr<HIR::Type> (lowered_type), + binding.get_locus ()); +} + HIR::GenericArgs ASTLoweringBase::lower_generic_args (AST::GenericArgs &args) { - std::vector<HIR::GenericArgsBinding> binding_args; // TODO + std::vector<HIR::GenericArgsBinding> binding_args; + for (auto &binding : args.get_binding_args ()) + { + HIR::GenericArgsBinding b = lower_binding (binding); + binding_args.push_back (std::move (b)); + } std::vector<HIR::Lifetime> lifetime_args; for (auto &lifetime : args.get_lifetime_args ()) diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h index ae22008..648999b 100644 --- a/gcc/rust/hir/tree/rust-hir-item.h +++ b/gcc/rust/hir/tree/rust-hir-item.h @@ -111,6 +111,18 @@ public: Identifier get_type_representation () const { return type_representation; } + std::unique_ptr<Type> &get_type () + { + rust_assert (type != nullptr); + return type; + } + + Analysis::NodeMapping get_type_mappings () const + { + rust_assert (type != nullptr); + return type->get_mappings (); + } + protected: // Clone function implementation as (not pure) virtual method TypeParam *clone_generic_param_impl () const override diff --git a/gcc/rust/hir/tree/rust-hir-path.h b/gcc/rust/hir/tree/rust-hir-path.h index 262a04a..c163487 100644 --- a/gcc/rust/hir/tree/rust-hir-path.h +++ b/gcc/rust/hir/tree/rust-hir-path.h @@ -107,6 +107,12 @@ public: GenericArgsBinding &operator= (GenericArgsBinding &&other) = default; std::string as_string () const; + + Identifier get_identifier () const { return identifier; } + + std::unique_ptr<Type> &get_type () { return type; } + + Location get_locus () const { return locus; } }; // Generic arguments allowed in each path expression segment - inline? diff --git a/gcc/rust/hir/tree/rust-hir.h b/gcc/rust/hir/tree/rust-hir.h index 9bda63a..244ff3d 100644 --- a/gcc/rust/hir/tree/rust-hir.h +++ b/gcc/rust/hir/tree/rust-hir.h @@ -1106,6 +1106,15 @@ class GenericParam public: virtual ~GenericParam () {} + enum GenericKind + { + TYPE, + LIFETIME, + + // CONST generic parameter not yet handled + // CONST, + }; + // Unique pointer custom clone function std::unique_ptr<GenericParam> clone_generic_param () const { @@ -1120,13 +1129,19 @@ public: Analysis::NodeMapping get_mappings () const { return mappings; } + enum GenericKind get_kind () const { return kind; } + protected: // Clone function implementation as pure virtual method virtual GenericParam *clone_generic_param_impl () const = 0; - GenericParam (Analysis::NodeMapping mapping) : mappings (mapping) {} - Analysis::NodeMapping mappings; + + enum GenericKind kind; + + GenericParam (Analysis::NodeMapping mapping, enum GenericKind kind = TYPE) + : mappings (mapping), kind (kind) + {} }; // A lifetime generic parameter (as opposed to a type generic parameter) @@ -1145,6 +1160,8 @@ class LifetimeParam : public GenericParam Location locus; public: + Lifetime get_lifetime () { return lifetime; } + // Returns whether the lifetime param has any lifetime bounds. bool has_lifetime_bounds () const { return !lifetime_bounds.empty (); } @@ -1160,7 +1177,8 @@ public: std::vector<Lifetime> lifetime_bounds = std::vector<Lifetime> (), Attribute outer_attr = Attribute::create_empty ()) - : GenericParam (mappings), lifetime (std::move (lifetime)), + : GenericParam (mappings, GenericKind::LIFETIME), + lifetime (std::move (lifetime)), lifetime_bounds (std::move (lifetime_bounds)), outer_attr (std::move (outer_attr)), locus (locus) {} @@ -1169,9 +1187,9 @@ public: // Copy constructor with clone LifetimeParam (LifetimeParam const &other) - : GenericParam (other.mappings), lifetime (other.lifetime), - lifetime_bounds (other.lifetime_bounds), outer_attr (other.outer_attr), - locus (other.locus) + : GenericParam (other.mappings, GenericKind::LIFETIME), + lifetime (other.lifetime), lifetime_bounds (other.lifetime_bounds), + outer_attr (other.outer_attr), locus (other.locus) {} // Overloaded assignment operator to clone attribute diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h index 3d61591..d249c43 100644 --- a/gcc/rust/resolve/rust-ast-resolve-type.h +++ b/gcc/rust/resolve/rust-ast-resolve-type.h @@ -252,6 +252,12 @@ public: return resolver.resolved_node; }; + void visit (AST::LifetimeParam ¶m) override + { + // For now do not do anything and accept everything. + ok = true; + } + void visit (AST::TypeParam ¶m) override { ok = true; diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.h b/gcc/rust/typecheck/rust-hir-type-check-implitem.h index 7426a75..2a3e9f9 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-implitem.h +++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.h @@ -59,12 +59,24 @@ public: { for (auto &generic_param : function.get_generic_params ()) { - auto param_type - = TypeResolveGenericParam::Resolve (generic_param.get ()); - context->insert_type (generic_param->get_mappings (), param_type); - - substitutions.push_back ( - TyTy::SubstitutionParamMapping (generic_param, param_type)); + switch (generic_param.get ()->get_kind ()) + { + case HIR::GenericParam::GenericKind::LIFETIME: + // Skipping Lifetime completely until better handling. + break; + + case HIR::GenericParam::GenericKind::TYPE: { + auto param_type + = TypeResolveGenericParam::Resolve (generic_param.get ()); + context->insert_type (generic_param->get_mappings (), + param_type); + + substitutions.push_back (TyTy::SubstitutionParamMapping ( + static_cast<HIR::TypeParam &> (*generic_param), + param_type)); + } + break; + } } } @@ -111,12 +123,24 @@ public: { for (auto &generic_param : method.get_generic_params ()) { - auto param_type - = TypeResolveGenericParam::Resolve (generic_param.get ()); - context->insert_type (generic_param->get_mappings (), param_type); - - substitutions.push_back ( - TyTy::SubstitutionParamMapping (generic_param, param_type)); + switch (generic_param.get ()->get_kind ()) + { + case HIR::GenericParam::GenericKind::LIFETIME: + // Skipping Lifetime completely until better handling. + break; + + case HIR::GenericParam::GenericKind::TYPE: { + auto param_type + = TypeResolveGenericParam::Resolve (generic_param.get ()); + context->insert_type (generic_param->get_mappings (), + param_type); + + substitutions.push_back (TyTy::SubstitutionParamMapping ( + static_cast<HIR::TypeParam &> (*generic_param), + param_type)); + } + break; + } } } @@ -180,7 +204,7 @@ private: TyTy::BaseType *self; std::vector<TyTy::SubstitutionParamMapping> substitutions; -}; +}; // namespace Resolver class TypeCheckImplItem : public TypeCheckBase { diff --git a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h index d1d5681..6be1552 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h +++ b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h @@ -55,12 +55,24 @@ public: { for (auto &generic_param : struct_decl.get_generic_params ()) { - auto param_type - = TypeResolveGenericParam::Resolve (generic_param.get ()); - context->insert_type (generic_param->get_mappings (), param_type); - - substitutions.push_back ( - TyTy::SubstitutionParamMapping (generic_param, param_type)); + switch (generic_param.get ()->get_kind ()) + { + case HIR::GenericParam::GenericKind::LIFETIME: + // Skipping Lifetime completely until better handling. + break; + + case HIR::GenericParam::GenericKind::TYPE: { + auto param_type + = TypeResolveGenericParam::Resolve (generic_param.get ()); + context->insert_type (generic_param->get_mappings (), + param_type); + + substitutions.push_back (TyTy::SubstitutionParamMapping ( + static_cast<HIR::TypeParam &> (*generic_param), + param_type)); + } + break; + } } } @@ -95,12 +107,24 @@ public: { for (auto &generic_param : struct_decl.get_generic_params ()) { - auto param_type - = TypeResolveGenericParam::Resolve (generic_param.get ()); - context->insert_type (generic_param->get_mappings (), param_type); - - substitutions.push_back ( - TyTy::SubstitutionParamMapping (generic_param, param_type)); + switch (generic_param.get ()->get_kind ()) + { + case HIR::GenericParam::GenericKind::LIFETIME: + // Skipping Lifetime completely until better handling. + break; + + case HIR::GenericParam::GenericKind::TYPE: { + auto param_type + = TypeResolveGenericParam::Resolve (generic_param.get ()); + context->insert_type (generic_param->get_mappings (), + param_type); + + substitutions.push_back (TyTy::SubstitutionParamMapping ( + static_cast<HIR::TypeParam &> (*generic_param), + param_type)); + } + break; + } } } @@ -152,12 +176,24 @@ public: { for (auto &generic_param : function.get_generic_params ()) { - auto param_type - = TypeResolveGenericParam::Resolve (generic_param.get ()); - context->insert_type (generic_param->get_mappings (), param_type); - - substitutions.push_back ( - TyTy::SubstitutionParamMapping (generic_param, param_type)); + switch (generic_param.get ()->get_kind ()) + { + case HIR::GenericParam::GenericKind::LIFETIME: + // Skipping Lifetime completely until better handling. + break; + + case HIR::GenericParam::GenericKind::TYPE: { + auto param_type + = TypeResolveGenericParam::Resolve (generic_param.get ()); + context->insert_type (generic_param->get_mappings (), + param_type); + + substitutions.push_back (TyTy::SubstitutionParamMapping ( + static_cast<HIR::TypeParam &> (*generic_param), + param_type)); + } + break; + } } } @@ -205,12 +241,24 @@ public: { for (auto &generic_param : impl_block.get_generic_params ()) { - auto param_type - = TypeResolveGenericParam::Resolve (generic_param.get ()); - context->insert_type (generic_param->get_mappings (), param_type); - - substitutions.push_back ( - TyTy::SubstitutionParamMapping (generic_param, param_type)); + switch (generic_param.get ()->get_kind ()) + { + case HIR::GenericParam::GenericKind::LIFETIME: + // Skipping Lifetime completely until better handling. + break; + + case HIR::GenericParam::GenericKind::TYPE: { + auto param_type + = TypeResolveGenericParam::Resolve (generic_param.get ()); + context->insert_type (generic_param->get_mappings (), + param_type); + + substitutions.push_back (TyTy::SubstitutionParamMapping ( + static_cast<HIR::TypeParam &> (*generic_param), + param_type)); + } + break; + } } } diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.h b/gcc/rust/typecheck/rust-hir-type-check-type.h index 74e3ed3..70b9cfa 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-type.h +++ b/gcc/rust/typecheck/rust-hir-type-check-type.h @@ -209,8 +209,7 @@ private: { std::string sym = mapping.get_param_ty ()->get_symbol (); param_tys.insert (sym); - param_location_map[sym] - = mapping.get_generic_param ()->get_locus_slow (); + param_location_map[sym] = mapping.get_generic_param ().get_locus (); } std::set<std::string> args; @@ -254,6 +253,11 @@ public: void visit (HIR::TypeParam ¶m) override { + TyTy::BaseType *default_ty_param = nullptr; + if (param.has_type ()) + { + default_ty_param = TypeCheckType::Resolve (param.get_type ().get ()); + } resolved = new TyTy::ParamType (param.get_type_representation (), param.get_mappings ().get_hirid (), param); } diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc index b75c139..3e9098d 100644 --- a/gcc/rust/typecheck/rust-tyty.cc +++ b/gcc/rust/typecheck/rust-tyty.cc @@ -211,16 +211,41 @@ SubstitutionParamMapping::override_context () SubstitutionArgumentMappings SubstitutionRef::get_mappings_from_generic_args (HIR::GenericArgs &args) { - if (args.get_type_args ().size () != substitutions.size ()) + if (args.get_binding_args ().size () > 0) { - rust_error_at (args.get_locus (), - "Invalid number of generic arguments to generic type"); + RichLocation r (args.get_locus ()); + for (auto &binding : args.get_binding_args ()) + r.add_range (binding.get_locus ()); + + rust_error_at (r, "associated type bindings are not allowed here"); return SubstitutionArgumentMappings::error (); } - std::vector<SubstitutionArg> mappings; + if (args.get_type_args ().size () > substitutions.size ()) + { + RichLocation r (args.get_locus ()); + r.add_range (substitutions.front ().get_param_locus ()); + + rust_error_at ( + r, + "generic item takes at most %lu type arguments but %lu were supplied", + substitutions.size (), args.get_type_args ().size ()); + return SubstitutionArgumentMappings::error (); + } + + if (args.get_type_args ().size () < min_required_substitutions ()) + { + RichLocation r (args.get_locus ()); + r.add_range (substitutions.front ().get_param_locus ()); + + rust_error_at ( + r, + "generic item takes at least %lu type arguments but %lu were supplied", + substitutions.size (), args.get_type_args ().size ()); + return SubstitutionArgumentMappings::error (); + } - // FIXME does not support binding yet + std::vector<SubstitutionArg> mappings; for (auto &arg : args.get_type_args ()) { BaseType *resolved = Resolver::TypeCheckType::Resolve (arg.get ()); @@ -235,6 +260,22 @@ SubstitutionRef::get_mappings_from_generic_args (HIR::GenericArgs &args) mappings.push_back (std::move (subst_arg)); } + // we must need to fill out defaults + size_t left_over + = num_required_substitutions () - min_required_substitutions (); + if (left_over > 0) + { + for (size_t offs = mappings.size (); offs < substitutions.size (); offs++) + { + SubstitutionParamMapping ¶m = substitutions.at (offs); + rust_assert (param.param_has_default_ty ()); + + BaseType *resolved = param.get_default_ty (); + SubstitutionArg subst_arg (¶m, resolved); + mappings.push_back (std::move (subst_arg)); + } + } + return SubstitutionArgumentMappings (mappings, args.get_locus ()); } diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h index bcc694b..d6a3aef 100644 --- a/gcc/rust/typecheck/rust-tyty.h +++ b/gcc/rust/typecheck/rust-tyty.h @@ -398,8 +398,7 @@ private: class SubstitutionParamMapping { public: - SubstitutionParamMapping (std::unique_ptr<HIR::GenericParam> &generic, - ParamType *param) + SubstitutionParamMapping (const HIR::TypeParam &generic, ParamType *param) : generic (generic), param (param) {} @@ -431,8 +430,10 @@ public: const ParamType *get_param_ty () const { return param; } - std::unique_ptr<HIR::GenericParam> &get_generic_param () { return generic; }; + const HIR::TypeParam &get_generic_param () { return generic; }; + // 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 void override_context (); bool needs_substitution () const @@ -444,8 +445,18 @@ public: return p->resolve ()->get_kind () == TypeKind::PARAM; } + Location get_param_locus () const { return generic.get_locus (); } + + bool param_has_default_ty () const { return generic.has_type (); } + + BaseType *get_default_ty () const + { + TyVar var (generic.get_type_mappings ().get_hirid ()); + return var.get_tyty (); + } + private: - std::unique_ptr<HIR::GenericParam> &generic; + const HIR::TypeParam &generic; ParamType *param; }; @@ -638,6 +649,7 @@ public: return used_arguments; } + // this is the count of type params that are not substituted fuly size_t num_required_substitutions () const { size_t n = 0; @@ -649,6 +661,19 @@ public: return n; } + // this is the count of type params that need substituted taking into account + // possible defaults + size_t min_required_substitutions () const + { + size_t n = 0; + for (auto &p : substitutions) + { + if (p.needs_substitution () && !p.param_has_default_ty ()) + n++; + } + return n; + } + // We are trying to subst <i32, f32> into Struct Foo<X,Y> {} // in the case of Foo<i32,f32>{...} // diff --git a/gcc/testsuite/rust.test/compile/generics23.rs b/gcc/testsuite/rust.test/compile/generics23.rs new file mode 100644 index 0000000..2169e36 --- /dev/null +++ b/gcc/testsuite/rust.test/compile/generics23.rs @@ -0,0 +1,6 @@ +struct Foo<A = f32>(A); + +fn main() { + let a: Foo; + a = Foo(123f32); +} diff --git a/gcc/testsuite/rust.test/compile/generics24.rs b/gcc/testsuite/rust.test/compile/generics24.rs new file mode 100644 index 0000000..9d24bce --- /dev/null +++ b/gcc/testsuite/rust.test/compile/generics24.rs @@ -0,0 +1,34 @@ +struct Foo<A = (isize, char)> { + a: A, +} + +impl Foo<isize> { + fn bar(self) -> isize { + self.a + } +} + +impl Foo<char> { + fn bar(self) -> char { + // { dg-warning "unused name" "" { target *-*-* } .-1 } + self.a + } +} + +impl Foo { + fn bar(self) { + let a: (isize, char) = self.a; + let b = a.0; + let c = a.1; + // { dg-warning "unused name" "" { target *-*-* } .-1 } + + let aa: Foo<isize> = Foo { a: b }; + let bb: isize = aa.bar(); + // { dg-warning "unused name" "" { target *-*-* } .-1 } + } +} + +fn main() { + let a = Foo { a: (123, 'a') }; + a.bar(); +} diff --git a/gcc/testsuite/rust.test/compile/lifetime1.rs b/gcc/testsuite/rust.test/compile/lifetime1.rs new file mode 100644 index 0000000..151fd82 --- /dev/null +++ b/gcc/testsuite/rust.test/compile/lifetime1.rs @@ -0,0 +1,7 @@ +fn foo<'a>(t: &'a str) -> &'a str { + t +} + +fn main() { + foo("hello world"); +} diff --git a/gcc/testsuite/rust.test/xfail_compile/expected_type_args2.rs b/gcc/testsuite/rust.test/xfail_compile/expected_type_args2.rs index b92c48f..4b1f704 100644 --- a/gcc/testsuite/rust.test/xfail_compile/expected_type_args2.rs +++ b/gcc/testsuite/rust.test/xfail_compile/expected_type_args2.rs @@ -2,5 +2,5 @@ struct Foo<A>(A); fn main() { let a: Foo = Foo::<i32>(123); - // { dg-error "Invalid number of generic arguments to generic type" "" { target { *-*-* } } .-1 } + // { dg-error "generic item takes at least 1 type arguments but 0 were supplied" "" { target { *-*-* } } .-1 } } diff --git a/gcc/testsuite/rust.test/xfail_compile/expected_type_args3.rs b/gcc/testsuite/rust.test/xfail_compile/expected_type_args3.rs index 4c164ff..dc70f76 100644 --- a/gcc/testsuite/rust.test/xfail_compile/expected_type_args3.rs +++ b/gcc/testsuite/rust.test/xfail_compile/expected_type_args3.rs @@ -1,7 +1,7 @@ struct Foo<A>(A); impl Foo { - // { dg-error "Invalid number of generic arguments to generic type" "" { target { *-*-* } } .-1 } + // { dg-error "generic item takes at least 1 type arguments but 0 were supplied" "" { target { *-*-* } } .-1 } fn test() -> i32 { 123 } diff --git a/gcc/testsuite/rust.test/xfail_compile/generics4.rs b/gcc/testsuite/rust.test/xfail_compile/generics4.rs index 0c18540..a831836 100644 --- a/gcc/testsuite/rust.test/xfail_compile/generics4.rs +++ b/gcc/testsuite/rust.test/xfail_compile/generics4.rs @@ -3,7 +3,7 @@ struct GenericStruct<T>(T, usize); fn main() { let a2; - a2 = GenericStruct::<i8, i32>(1, 456); // { dg-error "Invalid number of generic arguments to generic type" } + a2 = GenericStruct::<i8, i32>(1, 456); // { dg-error "generic item takes at most 1 type arguments but 2 were supplied" } let b2: i32 = a2.0; let c2: usize = a2.1; diff --git a/gcc/testsuite/rust.test/xfail_compile/type-bindings1.rs b/gcc/testsuite/rust.test/xfail_compile/type-bindings1.rs new file mode 100644 index 0000000..5e00f87 --- /dev/null +++ b/gcc/testsuite/rust.test/xfail_compile/type-bindings1.rs @@ -0,0 +1,8 @@ +// { dg-excess-errors "Noisy error and debug" } +struct Foo<A, B>(A, B); + +fn main() { + let a; + a = Foo::<A = i32, B = f32>(123f32); + // { dg-error "associated type bindings are not allowed here" "" { target { *-*-* } } .-1 } +} |