[gcc r14-7526] gccrs: Add mechanism use pattern information to improve type info
Arthur Cohen
cohenarthur@gcc.gnu.org
Tue Jan 16 17:41:33 GMT 2024
https://gcc.gnu.org/g:1b810614f1e4488b6f5c53a6d195fda51fb5a5e7
commit r14-7526-g1b810614f1e4488b6f5c53a6d195fda51fb5a5e7
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 f6359f94316..5fa9a1747a8 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 f82204872c1..3dafcd219c2 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 bde70768238..1221bcc6244 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 93afe693ffd..4bf371ffa06 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);
+}
More information about the Gcc-cvs
mailing list