public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] gccrs: Add mechanism use pattern information to improve type info
@ 2023-05-02  7:11 Thomas Schwinge
  0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2023-05-02  7:11 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:a14731ddb6ec67f21b5293affa3b1f8169a4bc92

commit a14731ddb6ec67f21b5293affa3b1f8169a4bc92
Author: Philip Herron <herron.philip@googlemail.com>
Date:   Sun Apr 23 22:41:21 2023 +0100

    gccrs: Add mechanism use pattern information to improve type info
    
    When we have an untyped closure we assumed all parameters were inference
    variables but we can use the pattern type to try and improve the type info
    so if we have a reference pattern it must be a reference to an inference
    variables '&_'. This patch adds a new visitor to figure this out for
    untyped closure parameters.
    
    Note this test case does fully type resolve into the gimple:
    
        bool test::main::{{closure}}
            (struct test::main::{{closure}} $closure, struct (& u8) args)
        { ... }
    
    Though the Rustc version does fail type-resolution but we make some
    assumptions during comparison expressions here that they resolve to a bool
    this will change when we implement the comparison lang items.
    
    Fixes #2142
    
    gcc/rust/ChangeLog:
    
            * hir/tree/rust-hir-pattern.h: add missing get_mutability
            * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit):
            use new ClosureParamInfer on untyped parameters
            * typecheck/rust-hir-type-check-pattern.cc (ClosureParamInfer::Resolve): interface
            (ClosureParamInfer::ClosureParamInfer): constructor
            (ClosureParamInfer::visit): visitors for each pattern
            * typecheck/rust-hir-type-check-pattern.h (class ClosureParamInfer): new visitor
    
    gcc/testsuite/ChangeLog:
    
            * rust/compile/issue-2142.rs: New test.
    
    Signed-off-by: Philip Herron <herron.philip@googlemail.com>

Diff:
---
 gcc/rust/hir/tree/rust-hir-pattern.h              |   2 +
 gcc/rust/typecheck/rust-hir-type-check-expr.cc    |  21 ++--
 gcc/rust/typecheck/rust-hir-type-check-pattern.cc | 111 ++++++++++++++++++++++
 gcc/rust/typecheck/rust-hir-type-check-pattern.h  |  24 +++++
 gcc/testsuite/rust/compile/issue-2142.rs          |  14 +++
 5 files changed, 159 insertions(+), 13 deletions(-)

diff --git a/gcc/rust/hir/tree/rust-hir-pattern.h b/gcc/rust/hir/tree/rust-hir-pattern.h
index 32292a85f8a..cb95f40d2d8 100644
--- a/gcc/rust/hir/tree/rust-hir-pattern.h
+++ b/gcc/rust/hir/tree/rust-hir-pattern.h
@@ -462,6 +462,8 @@ public:
 
   bool is_mut () const { return mut == Mutability::Mut; }
 
+  Mutability get_mutability () const { return mut; }
+
   void accept_vis (HIRFullVisitor &vis) override;
   void accept_vis (HIRPatternVisitor &vis) override;
 
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 42b9623fad6..704ca2b9e5b 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -1471,25 +1471,20 @@ TypeCheckExpr::visit (HIR::ClosureExpr &expr)
   std::vector<TyTy::TyVar> parameter_types;
   for (auto &p : expr.get_params ())
     {
+      TyTy::BaseType *param_tyty = nullptr;
       if (p.has_type_given ())
 	{
-	  TyTy::BaseType *param_tyty
-	    = TypeCheckType::Resolve (p.get_type ().get ());
-	  TyTy::TyVar param_ty (param_tyty->get_ref ());
-	  parameter_types.push_back (param_ty);
-
-	  TypeCheckPattern::Resolve (p.get_pattern ().get (),
-				     param_ty.get_tyty ());
+	  param_tyty = TypeCheckType::Resolve (p.get_type ().get ());
 	}
       else
 	{
-	  TyTy::TyVar param_ty
-	    = TyTy::TyVar::get_implicit_infer_var (p.get_locus ());
-	  parameter_types.push_back (param_ty);
-
-	  TypeCheckPattern::Resolve (p.get_pattern ().get (),
-				     param_ty.get_tyty ());
+	  param_tyty = ClosureParamInfer::Resolve (p.get_pattern ().get ());
 	}
+
+      TyTy::TyVar param_ty (param_tyty->get_ref ());
+      parameter_types.push_back (param_ty);
+
+      TypeCheckPattern::Resolve (p.get_pattern ().get (), param_ty.get_tyty ());
     }
 
   // we generate an implicit hirid for the closure args
diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
index edd4ceb48ae..466f0ae2223 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
@@ -447,5 +447,116 @@ TypeCheckPattern::visit (HIR::AltPattern &pattern)
 		 "type checking alternate patterns not supported");
 }
 
+TyTy::BaseType *
+ClosureParamInfer::Resolve (HIR::Pattern *pattern)
+{
+  ClosureParamInfer resolver;
+  pattern->accept_vis (resolver);
+
+  if (resolver.infered->get_kind () != TyTy::TypeKind::ERROR)
+    {
+      resolver.context->insert_implicit_type (resolver.infered);
+      resolver.mappings->insert_location (resolver.infered->get_ref (),
+					  pattern->get_locus ());
+    }
+  return resolver.infered;
+}
+
+ClosureParamInfer::ClosureParamInfer ()
+  : TypeCheckBase (), infered (new TyTy::ErrorType (0))
+{}
+
+void
+ClosureParamInfer::visit (HIR::WildcardPattern &pattern)
+{
+  HirId id = pattern.get_pattern_mappings ().get_hirid ();
+  infered = new TyTy::InferType (id, TyTy::InferType::InferTypeKind::GENERAL,
+				 TyTy::InferType::TypeHint::Default (),
+				 pattern.get_locus ());
+}
+
+void
+ClosureParamInfer::visit (HIR::IdentifierPattern &pattern)
+{
+  HirId id = pattern.get_pattern_mappings ().get_hirid ();
+  infered = new TyTy::InferType (id, TyTy::InferType::InferTypeKind::GENERAL,
+				 TyTy::InferType::TypeHint::Default (),
+				 pattern.get_locus ());
+}
+
+void
+ClosureParamInfer::visit (HIR::ReferencePattern &pattern)
+{
+  TyTy::BaseType *element
+    = ClosureParamInfer::Resolve (pattern.get_referenced_pattern ().get ());
+
+  HirId id = pattern.get_pattern_mappings ().get_hirid ();
+  infered = new TyTy::ReferenceType (id, TyTy::TyVar (element->get_ref ()),
+				     pattern.get_mutability ());
+}
+
+void
+ClosureParamInfer::visit (HIR::PathInExpression &pattern)
+{
+  rust_sorry_at (pattern.get_locus (),
+		 "unable to infer this kind of parameter pattern");
+}
+
+void
+ClosureParamInfer::visit (HIR::StructPattern &pattern)
+{
+  rust_sorry_at (pattern.get_locus (),
+		 "unable to infer this kind of parameter pattern");
+}
+
+void
+ClosureParamInfer::visit (HIR::TupleStructPattern &pattern)
+{
+  rust_sorry_at (pattern.get_locus (),
+		 "unable to infer this kind of parameter pattern");
+}
+
+void
+ClosureParamInfer::visit (HIR::TuplePattern &pattern)
+{
+  rust_sorry_at (pattern.get_locus (),
+		 "unable to infer this kind of parameter pattern");
+}
+
+void
+ClosureParamInfer::visit (HIR::LiteralPattern &pattern)
+{
+  rust_sorry_at (pattern.get_locus (),
+		 "unable to infer this kind of parameter pattern");
+}
+
+void
+ClosureParamInfer::visit (HIR::RangePattern &pattern)
+{
+  rust_sorry_at (pattern.get_locus (),
+		 "unable to infer this kind of parameter pattern");
+}
+
+void
+ClosureParamInfer::visit (HIR::QualifiedPathInExpression &pattern)
+{
+  rust_sorry_at (pattern.get_locus (),
+		 "unable to infer this kind of parameter pattern");
+}
+
+void
+ClosureParamInfer::visit (HIR::SlicePattern &pattern)
+{
+  rust_sorry_at (pattern.get_locus (),
+		 "unable to infer this kind of parameter pattern");
+}
+
+void
+ClosureParamInfer::visit (HIR::AltPattern &pattern)
+{
+  rust_sorry_at (pattern.get_locus (),
+		 "unable to infer this kind of parameter pattern");
+}
+
 } // namespace Resolver
 } // namespace Rust
diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.h b/gcc/rust/typecheck/rust-hir-type-check-pattern.h
index d4a1d206628..709e8be4c86 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-pattern.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.h
@@ -58,6 +58,30 @@ private:
   TyTy::BaseType *infered;
 };
 
+class ClosureParamInfer : private TypeCheckBase, private HIR::HIRPatternVisitor
+{
+public:
+  static TyTy::BaseType *Resolve (HIR::Pattern *pattern);
+
+  void visit (HIR::PathInExpression &pattern) override;
+  void visit (HIR::StructPattern &pattern) override;
+  void visit (HIR::TupleStructPattern &pattern) override;
+  void visit (HIR::WildcardPattern &pattern) override;
+  void visit (HIR::TuplePattern &pattern) override;
+  void visit (HIR::LiteralPattern &pattern) override;
+  void visit (HIR::RangePattern &pattern) override;
+  void visit (HIR::IdentifierPattern &pattern) override;
+  void visit (HIR::QualifiedPathInExpression &pattern) override;
+  void visit (HIR::ReferencePattern &pattern) override;
+  void visit (HIR::SlicePattern &pattern) override;
+  void visit (HIR::AltPattern &pattern) override;
+
+private:
+  ClosureParamInfer ();
+
+  TyTy::BaseType *infered;
+};
+
 } // namespace Resolver
 } // namespace Rust
 
diff --git a/gcc/testsuite/rust/compile/issue-2142.rs b/gcc/testsuite/rust/compile/issue-2142.rs
new file mode 100644
index 00000000000..7a8bb2aca50
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2142.rs
@@ -0,0 +1,14 @@
+#[lang = "fn_once"]
+pub trait FnOnce<Args> {
+    #[lang = "fn_once_output"]
+    type Output;
+
+    extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+fn main() {
+    let lambda = |&c| c != b'9';
+
+    let a = b'1';
+    lambda(&a);
+}

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-05-02  7:11 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-02  7:11 [gcc/devel/rust/master] gccrs: Add mechanism use pattern information to improve type info Thomas Schwinge

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).