From eb2c6124c46d0b3d58630c80af007ed092adc1ea Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Thu, 29 Apr 2021 13:16:26 +0100 Subject: Improve error messages of unexpected arguments When we get GenericBindings such as :: this is not allowed int this context. We can also improve the unexpected number of argument errors to print the number of expected vs received arguments. --- gcc/rust/typecheck/rust-tyty.cc | 24 ++++++++++++++++++---- .../rust.test/xfail_compile/expected_type_args2.rs | 2 +- .../rust.test/xfail_compile/expected_type_args3.rs | 2 +- gcc/testsuite/rust.test/xfail_compile/generics4.rs | 2 +- 4 files changed, 23 insertions(+), 7 deletions(-) (limited to 'gcc') diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc index b75c139..c8f5f19 100644 --- a/gcc/rust/typecheck/rust-tyty.cc +++ b/gcc/rust/typecheck/rust-tyty.cc @@ -211,16 +211,32 @@ 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"); + "associated type bindings are not allowed here"); return SubstitutionArgumentMappings::error (); } - std::vector mappings; + if (args.get_type_args ().size () > substitutions.size ()) + { + rust_error_at ( + args.get_locus (), + "generic item takes at most %lu type arguments but %lu were supplied", + substitutions.size (), args.get_type_args ().size ()); + return SubstitutionArgumentMappings::error (); + } - // FIXME does not support binding yet + if (args.get_type_args ().size () < substitutions.size ()) + { + rust_error_at ( + args.get_locus (), + "generic item takes at least %lu type arguments but %lu were supplied", + substitutions.size (), args.get_type_args ().size ()); + return SubstitutionArgumentMappings::error (); + } + + std::vector mappings; for (auto &arg : args.get_type_args ()) { BaseType *resolved = Resolver::TypeCheckType::Resolve (arg.get ()); 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); fn main() { let a: Foo = Foo::(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); 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, usize); fn main() { let a2; - a2 = GenericStruct::(1, 456); // { dg-error "Invalid number of generic arguments to generic type" } + a2 = GenericStruct::(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; -- cgit v1.1 From c1296bc68e0b94285bbbab89a63ae44520d812ac Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Thu, 29 Apr 2021 13:56:37 +0100 Subject: Add HIR lowering for GenericBindingArgs We need to lower the bindings for defaults in the GenericArgs structure. We can also take advantage of RichLocations further improving the diagnostic errors here. --- gcc/rust/ast/rust-path.h | 4 ++++ gcc/rust/hir/rust-ast-lower-base.h | 2 ++ gcc/rust/hir/rust-ast-lower.cc | 17 ++++++++++++++++- gcc/rust/hir/tree/rust-hir-path.h | 6 ++++++ gcc/rust/typecheck/rust-tyty.cc | 17 +++++++++++++---- gcc/rust/typecheck/rust-tyty.h | 2 ++ gcc/testsuite/rust.test/xfail_compile/type-bindings1.rs | 8 ++++++++ 7 files changed, 51 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/rust.test/xfail_compile/type-bindings1.rs (limited to 'gcc') 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.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 (lowered_type), + binding.get_locus ()); +} + HIR::GenericArgs ASTLoweringBase::lower_generic_args (AST::GenericArgs &args) { - std::vector binding_args; // TODO + std::vector binding_args; + for (auto &binding : args.get_binding_args ()) + { + HIR::GenericArgsBinding b = lower_binding (binding); + binding_args.push_back (std::move (b)); + } std::vector lifetime_args; for (auto &lifetime : args.get_lifetime_args ()) 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 &get_type () { return type; } + + Location get_locus () const { return locus; } }; // Generic arguments allowed in each path expression segment - inline? diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc index c8f5f19..be56dc7 100644 --- a/gcc/rust/typecheck/rust-tyty.cc +++ b/gcc/rust/typecheck/rust-tyty.cc @@ -213,15 +213,21 @@ SubstitutionRef::get_mappings_from_generic_args (HIR::GenericArgs &args) { if (args.get_binding_args ().size () > 0) { - rust_error_at (args.get_locus (), - "associated type bindings are not allowed here"); + 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 (); } if (args.get_type_args ().size () > substitutions.size ()) { + RichLocation r (args.get_locus ()); + r.add_range (substitutions.front ().get_param_locus ()); + rust_error_at ( - args.get_locus (), + r, "generic item takes at most %lu type arguments but %lu were supplied", substitutions.size (), args.get_type_args ().size ()); return SubstitutionArgumentMappings::error (); @@ -229,8 +235,11 @@ SubstitutionRef::get_mappings_from_generic_args (HIR::GenericArgs &args) if (args.get_type_args ().size () < substitutions.size ()) { + RichLocation r (args.get_locus ()); + r.add_range (substitutions.front ().get_param_locus ()); + rust_error_at ( - args.get_locus (), + r, "generic item takes at least %lu type arguments but %lu were supplied", substitutions.size (), args.get_type_args ().size ()); return SubstitutionArgumentMappings::error (); diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h index bcc694b..91c3f06 100644 --- a/gcc/rust/typecheck/rust-tyty.h +++ b/gcc/rust/typecheck/rust-tyty.h @@ -444,6 +444,8 @@ public: return p->resolve ()->get_kind () == TypeKind::PARAM; } + Location get_param_locus () const { return generic->get_locus_slow (); } + private: std::unique_ptr &generic; ParamType *param; 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); + +fn main() { + let a; + a = Foo::(123f32); + // { dg-error "associated type bindings are not allowed here" "" { target { *-*-* } } .-1 } +} -- cgit v1.1 From 5d9855c69a23278780bdbd64a14cc8073497f6e3 Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Thu, 29 Apr 2021 18:30:16 +0100 Subject: Refactor to GenericParam to TypeParam in parameter mappings When we have Parameter mappings these _must_ be TypeParams this allows us to access the specified defaults if they exist. --- gcc/rust/typecheck/rust-hir-type-check-implitem.h | 8 ++++---- gcc/rust/typecheck/rust-hir-type-check-toplevel.h | 16 ++++++++-------- gcc/rust/typecheck/rust-hir-type-check-type.h | 3 +-- gcc/rust/typecheck/rust-tyty.h | 11 ++++++----- 4 files changed, 19 insertions(+), 19 deletions(-) (limited to 'gcc') diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.h b/gcc/rust/typecheck/rust-hir-type-check-implitem.h index 7426a75..8ab20cf 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-implitem.h +++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.h @@ -63,8 +63,8 @@ public: = TypeResolveGenericParam::Resolve (generic_param.get ()); context->insert_type (generic_param->get_mappings (), param_type); - substitutions.push_back ( - TyTy::SubstitutionParamMapping (generic_param, param_type)); + substitutions.push_back (TyTy::SubstitutionParamMapping ( + static_cast (*generic_param), param_type)); } } @@ -115,8 +115,8 @@ public: = TypeResolveGenericParam::Resolve (generic_param.get ()); context->insert_type (generic_param->get_mappings (), param_type); - substitutions.push_back ( - TyTy::SubstitutionParamMapping (generic_param, param_type)); + substitutions.push_back (TyTy::SubstitutionParamMapping ( + static_cast (*generic_param), param_type)); } } diff --git a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h index d1d5681..1bfa7fb 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h +++ b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h @@ -59,8 +59,8 @@ public: = TypeResolveGenericParam::Resolve (generic_param.get ()); context->insert_type (generic_param->get_mappings (), param_type); - substitutions.push_back ( - TyTy::SubstitutionParamMapping (generic_param, param_type)); + substitutions.push_back (TyTy::SubstitutionParamMapping ( + static_cast (*generic_param), param_type)); } } @@ -99,8 +99,8 @@ public: = TypeResolveGenericParam::Resolve (generic_param.get ()); context->insert_type (generic_param->get_mappings (), param_type); - substitutions.push_back ( - TyTy::SubstitutionParamMapping (generic_param, param_type)); + substitutions.push_back (TyTy::SubstitutionParamMapping ( + static_cast (*generic_param), param_type)); } } @@ -156,8 +156,8 @@ public: = TypeResolveGenericParam::Resolve (generic_param.get ()); context->insert_type (generic_param->get_mappings (), param_type); - substitutions.push_back ( - TyTy::SubstitutionParamMapping (generic_param, param_type)); + substitutions.push_back (TyTy::SubstitutionParamMapping ( + static_cast (*generic_param), param_type)); } } @@ -209,8 +209,8 @@ public: = TypeResolveGenericParam::Resolve (generic_param.get ()); context->insert_type (generic_param->get_mappings (), param_type); - substitutions.push_back ( - TyTy::SubstitutionParamMapping (generic_param, param_type)); + substitutions.push_back (TyTy::SubstitutionParamMapping ( + static_cast (*generic_param), param_type)); } } diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.h b/gcc/rust/typecheck/rust-hir-type-check-type.h index 74e3ed3..d8a3f29 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 args; diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h index 91c3f06..ee13532 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 &generic, - ParamType *param) + SubstitutionParamMapping (const HIR::TypeParam &generic, ParamType *param) : generic (generic), param (param) {} @@ -431,7 +430,7 @@ public: const ParamType *get_param_ty () const { return param; } - std::unique_ptr &get_generic_param () { return generic; }; + const HIR::TypeParam &get_generic_param () { return generic; }; void override_context (); @@ -444,10 +443,12 @@ public: return p->resolve ()->get_kind () == TypeKind::PARAM; } - Location get_param_locus () const { return generic->get_locus_slow (); } + Location get_param_locus () const { return generic.get_locus (); } + + bool param_has_default_ty () const { return generic.has_type (); } private: - std::unique_ptr &generic; + const HIR::TypeParam &generic; ParamType *param; }; -- cgit v1.1 From 682cae549a4eb29857f49fe72cf130e2ee577d8c Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Thu, 29 Apr 2021 18:38:51 +0100 Subject: Add missing comment for override_context --- gcc/rust/typecheck/rust-tyty.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'gcc') diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h index ee13532..5beedda 100644 --- a/gcc/rust/typecheck/rust-tyty.h +++ b/gcc/rust/typecheck/rust-tyty.h @@ -432,6 +432,8 @@ public: 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 -- cgit v1.1 From ffa45bed5e9211c7d2ee242f63fd6c3118248177 Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Fri, 30 Apr 2021 10:08:15 +0100 Subject: Typecheck the default type on TypeParam --- gcc/rust/hir/tree/rust-hir-item.h | 6 ++++++ gcc/rust/typecheck/rust-hir-type-check-type.h | 5 +++++ 2 files changed, 11 insertions(+) (limited to 'gcc') diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h index ae22008..dbbc743 100644 --- a/gcc/rust/hir/tree/rust-hir-item.h +++ b/gcc/rust/hir/tree/rust-hir-item.h @@ -111,6 +111,12 @@ public: Identifier get_type_representation () const { return type_representation; } + std::unique_ptr &get_type () + { + rust_assert (type != nullptr); + return type; + } + protected: // Clone function implementation as (not pure) virtual method TypeParam *clone_generic_param_impl () const override diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.h b/gcc/rust/typecheck/rust-hir-type-check-type.h index d8a3f29..70b9cfa 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-type.h +++ b/gcc/rust/typecheck/rust-hir-type-check-type.h @@ -253,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); } -- cgit v1.1 From 91ca22c7b9141364aa4bebc61e46ae1518b793f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Poulhi=C3=A8s?= Date: Mon, 26 Apr 2021 21:15:19 +0200 Subject: Basic support for lifetime parameter This change allow for basic lifetime usage. Only syntax is checked, nothing more. Goal is to be able to compile known-to-be-valid code. Addresses #359 --- gcc/rust/ast/rust-ast.h | 2 + gcc/rust/hir/rust-ast-lower-type.h | 28 +++++++ gcc/rust/hir/tree/rust-hir.h | 30 +++++-- gcc/rust/resolve/rust-ast-resolve-type.h | 6 ++ gcc/rust/typecheck/rust-hir-type-check-implitem.h | 50 +++++++++--- gcc/rust/typecheck/rust-hir-type-check-toplevel.h | 96 +++++++++++++++++------ gcc/testsuite/rust.test/compile/lifetime1.rs | 7 ++ 7 files changed, 176 insertions(+), 43 deletions(-) create mode 100644 gcc/testsuite/rust.test/compile/lifetime1.rs (limited to 'gcc') 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/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 ()); + } + void visit (AST::TypeParam ¶m) override { HIR::Attribute outer_attr = HIR::Attribute::create_empty (); 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 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_bounds = std::vector (), 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 8ab20cf..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 ( - static_cast (*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 (*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 ( - static_cast (*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 (*generic_param), + param_type)); + } + break; + } } } @@ -180,7 +204,7 @@ private: TyTy::BaseType *self; std::vector 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 1bfa7fb..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 ( - static_cast (*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 (*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 ( - static_cast (*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 (*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 ( - static_cast (*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 (*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 ( - static_cast (*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 (*generic_param), + param_type)); + } + break; + } } } 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"); +} -- cgit v1.1 From b7d95ea80be40c5ee468a5549d84e058a21fc62c Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Fri, 30 Apr 2021 11:48:20 +0100 Subject: Add initial support for defaults on generic parameters In the case that the GenericArgs to a type/fn are less than the expected number of required substitutions we need to look for what is the min number of required substitutions which might be zero if each TypeParam has a default. In the event we have less than expected arguments we can substitute the defaults if available as the GenericArgumentMappings. Addresses: #307 --- gcc/rust/hir/tree/rust-hir-item.h | 6 +++++ gcc/rust/typecheck/rust-tyty.cc | 18 +++++++++++++- gcc/rust/typecheck/rust-tyty.h | 20 ++++++++++++++++ gcc/testsuite/rust.test/compile/generics23.rs | 6 +++++ gcc/testsuite/rust.test/compile/generics24.rs | 34 +++++++++++++++++++++++++++ 5 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/rust.test/compile/generics23.rs create mode 100644 gcc/testsuite/rust.test/compile/generics24.rs (limited to 'gcc') diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h index dbbc743..648999b 100644 --- a/gcc/rust/hir/tree/rust-hir-item.h +++ b/gcc/rust/hir/tree/rust-hir-item.h @@ -117,6 +117,12 @@ public: 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/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc index be56dc7..3e9098d 100644 --- a/gcc/rust/typecheck/rust-tyty.cc +++ b/gcc/rust/typecheck/rust-tyty.cc @@ -233,7 +233,7 @@ SubstitutionRef::get_mappings_from_generic_args (HIR::GenericArgs &args) return SubstitutionArgumentMappings::error (); } - if (args.get_type_args ().size () < substitutions.size ()) + if (args.get_type_args ().size () < min_required_substitutions ()) { RichLocation r (args.get_locus ()); r.add_range (substitutions.front ().get_param_locus ()); @@ -260,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 5beedda..d6a3aef 100644 --- a/gcc/rust/typecheck/rust-tyty.h +++ b/gcc/rust/typecheck/rust-tyty.h @@ -449,6 +449,12 @@ public: 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: const HIR::TypeParam &generic; ParamType *param; @@ -643,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; @@ -654,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 into Struct Foo {} // in the case of Foo{...} // 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); + +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: A, +} + +impl Foo { + fn bar(self) -> isize { + self.a + } +} + +impl Foo { + 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 = Foo { a: b }; + let bb: isize = aa.bar(); + // { dg-warning "unused name" "" { target *-*-* } .-1 } + } +} + +fn main() { + let a = Foo { a: (123, 'a') }; + a.bar(); +} -- cgit v1.1