diff options
author | Marc Poulhiès <dkm@kataplop.net> | 2021-04-26 21:15:19 +0200 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2021-04-30 10:39:39 +0100 |
commit | 91ca22c7b9141364aa4bebc61e46ae1518b793f3 (patch) | |
tree | 1385701e6f3d93b26ed330819a1269df766a5f33 | |
parent | ffa45bed5e9211c7d2ee242f63fd6c3118248177 (diff) | |
download | gcc-91ca22c7b9141364aa4bebc61e46ae1518b793f3.zip gcc-91ca22c7b9141364aa4bebc61e46ae1518b793f3.tar.gz gcc-91ca22c7b9141364aa4bebc61e46ae1518b793f3.tar.bz2 |
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
-rw-r--r-- | gcc/rust/ast/rust-ast.h | 2 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-type.h | 28 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir.h | 30 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-type.h | 6 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-implitem.h | 50 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-toplevel.h | 96 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/compile/lifetime1.rs | 7 |
7 files changed, 176 insertions, 43 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/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/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 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<HIR::TypeParam &> (*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 ( - static_cast<HIR::TypeParam &> (*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 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<HIR::TypeParam &> (*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 ( - static_cast<HIR::TypeParam &> (*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 ( - static_cast<HIR::TypeParam &> (*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 ( - static_cast<HIR::TypeParam &> (*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/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"); +} |