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