]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: add missing name resolution to self params with specified types
authorPhilip Herron <herron.philip@googlemail.com>
Wed, 29 Mar 2023 13:24:12 +0000 (14:24 +0100)
committerArthur Cohen <arthur.cohen@embecosm.com>
Tue, 16 Jan 2024 17:28:42 +0000 (18:28 +0100)
In rust it is possible to write method where you explicitly specify the
type of a self param. It does not however allow for you to use reference
destructuring in this senario.

gcc/rust/ChangeLog:

* resolve/rust-ast-resolve-item.cc
(ResolveTraitItems::visit): add name resolution self param
(ResolveItem::visit): likewise

Signed-off-by: Philip Herron <herron.philip@googlemail.com>
gcc/rust/resolve/rust-ast-resolve-item.cc

index c1590ca3a2fdd89c0e610265b64c4f4eeb63f57e..a73c9ee3ecee94a4dbbd59771577d2bc2124dec4 100644 (file)
@@ -138,16 +138,31 @@ ResolveTraitItems::visit (AST::TraitItemMethod &func)
                                       self_param.get_has_ref (),
                                       self_param.get_is_mut (),
                                       std::unique_ptr<AST::Pattern> (nullptr));
-
-  std::vector<std::unique_ptr<AST::TypePathSegment>> segments;
-  segments.push_back (std::unique_ptr<AST::TypePathSegment> (
-    new AST::TypePathSegment ("Self", false, self_param.get_locus ())));
-
-  AST::TypePath self_type_path (std::move (segments), self_param.get_locus ());
-
-  ResolveType::go (&self_type_path);
   PatternDeclaration::go (&self_pattern, Rib::ItemType::Param);
 
+  if (self_param.has_type ())
+    {
+      if (self_param.get_has_ref ())
+       {
+         // FIXME is this true?
+         rust_error_at (
+           self_param.get_locus (),
+           "it is not possible to mark self as reference and specify type");
+       }
+      ResolveType::go (self_param.get_type ().get ());
+    }
+  else
+    {
+      // here we implicitly make self have a type path of Self
+      std::vector<std::unique_ptr<AST::TypePathSegment>> segments;
+      segments.push_back (std::unique_ptr<AST::TypePathSegment> (
+       new AST::TypePathSegment ("Self", false, self_param.get_locus ())));
+
+      AST::TypePath self_type_path (std::move (segments),
+                                   self_param.get_locus ());
+      ResolveType::go (&self_type_path);
+    }
+
   std::vector<PatternBinding> bindings
     = {PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ())};
 
@@ -636,16 +651,31 @@ ResolveItem::visit (AST::Method &method)
                                       self_param.get_has_ref (),
                                       self_param.get_is_mut (),
                                       std::unique_ptr<AST::Pattern> (nullptr));
-
-  std::vector<std::unique_ptr<AST::TypePathSegment>> segments;
-  segments.push_back (std::unique_ptr<AST::TypePathSegment> (
-    new AST::TypePathSegment ("Self", false, self_param.get_locus ())));
-
-  AST::TypePath self_type_path (std::move (segments), self_param.get_locus ());
-
-  ResolveType::go (&self_type_path);
   PatternDeclaration::go (&self_pattern, Rib::ItemType::Param);
 
+  if (self_param.has_type ())
+    {
+      if (self_param.get_has_ref ())
+       {
+         // FIXME is this true?
+         rust_error_at (
+           self_param.get_locus (),
+           "it is not possible to mark self as reference and specify type");
+       }
+      ResolveType::go (self_param.get_type ().get ());
+    }
+  else
+    {
+      // here we implicitly make self have a type path of Self
+      std::vector<std::unique_ptr<AST::TypePathSegment>> segments;
+      segments.push_back (std::unique_ptr<AST::TypePathSegment> (
+       new AST::TypePathSegment ("Self", false, self_param.get_locus ())));
+
+      AST::TypePath self_type_path (std::move (segments),
+                                   self_param.get_locus ());
+      ResolveType::go (&self_type_path);
+    }
+
   std::vector<PatternBinding> bindings
     = {PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ())};