Skip to content

Commit 99ed358

Browse files
philbertyCohenArthur
authored andcommitted
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 Rust-GCC#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 <[email protected]>
1 parent d09c537 commit 99ed358

File tree

5 files changed

+159
-13
lines changed

5 files changed

+159
-13
lines changed

gcc/rust/hir/tree/rust-hir-pattern.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,8 @@ class ReferencePattern : public Pattern
462462

463463
bool is_mut () const { return mut == Mutability::Mut; }
464464

465+
Mutability get_mutability () const { return mut; }
466+
465467
void accept_vis (HIRFullVisitor &vis) override;
466468
void accept_vis (HIRPatternVisitor &vis) override;
467469

gcc/rust/typecheck/rust-hir-type-check-expr.cc

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1471,25 +1471,20 @@ TypeCheckExpr::visit (HIR::ClosureExpr &expr)
14711471
std::vector<TyTy::TyVar> parameter_types;
14721472
for (auto &p : expr.get_params ())
14731473
{
1474+
TyTy::BaseType *param_tyty = nullptr;
14741475
if (p.has_type_given ())
14751476
{
1476-
TyTy::BaseType *param_tyty
1477-
= TypeCheckType::Resolve (p.get_type ().get ());
1478-
TyTy::TyVar param_ty (param_tyty->get_ref ());
1479-
parameter_types.push_back (param_ty);
1480-
1481-
TypeCheckPattern::Resolve (p.get_pattern ().get (),
1482-
param_ty.get_tyty ());
1477+
param_tyty = TypeCheckType::Resolve (p.get_type ().get ());
14831478
}
14841479
else
14851480
{
1486-
TyTy::TyVar param_ty
1487-
= TyTy::TyVar::get_implicit_infer_var (p.get_locus ());
1488-
parameter_types.push_back (param_ty);
1489-
1490-
TypeCheckPattern::Resolve (p.get_pattern ().get (),
1491-
param_ty.get_tyty ());
1481+
param_tyty = ClosureParamInfer::Resolve (p.get_pattern ().get ());
14921482
}
1483+
1484+
TyTy::TyVar param_ty (param_tyty->get_ref ());
1485+
parameter_types.push_back (param_ty);
1486+
1487+
TypeCheckPattern::Resolve (p.get_pattern ().get (), param_ty.get_tyty ());
14931488
}
14941489

14951490
// we generate an implicit hirid for the closure args

gcc/rust/typecheck/rust-hir-type-check-pattern.cc

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,5 +447,116 @@ TypeCheckPattern::visit (HIR::AltPattern &pattern)
447447
"type checking alternate patterns not supported");
448448
}
449449

450+
TyTy::BaseType *
451+
ClosureParamInfer::Resolve (HIR::Pattern *pattern)
452+
{
453+
ClosureParamInfer resolver;
454+
pattern->accept_vis (resolver);
455+
456+
if (resolver.infered->get_kind () != TyTy::TypeKind::ERROR)
457+
{
458+
resolver.context->insert_implicit_type (resolver.infered);
459+
resolver.mappings->insert_location (resolver.infered->get_ref (),
460+
pattern->get_locus ());
461+
}
462+
return resolver.infered;
463+
}
464+
465+
ClosureParamInfer::ClosureParamInfer ()
466+
: TypeCheckBase (), infered (new TyTy::ErrorType (0))
467+
{}
468+
469+
void
470+
ClosureParamInfer::visit (HIR::WildcardPattern &pattern)
471+
{
472+
HirId id = pattern.get_pattern_mappings ().get_hirid ();
473+
infered = new TyTy::InferType (id, TyTy::InferType::InferTypeKind::GENERAL,
474+
TyTy::InferType::TypeHint::Default (),
475+
pattern.get_locus ());
476+
}
477+
478+
void
479+
ClosureParamInfer::visit (HIR::IdentifierPattern &pattern)
480+
{
481+
HirId id = pattern.get_pattern_mappings ().get_hirid ();
482+
infered = new TyTy::InferType (id, TyTy::InferType::InferTypeKind::GENERAL,
483+
TyTy::InferType::TypeHint::Default (),
484+
pattern.get_locus ());
485+
}
486+
487+
void
488+
ClosureParamInfer::visit (HIR::ReferencePattern &pattern)
489+
{
490+
TyTy::BaseType *element
491+
= ClosureParamInfer::Resolve (pattern.get_referenced_pattern ().get ());
492+
493+
HirId id = pattern.get_pattern_mappings ().get_hirid ();
494+
infered = new TyTy::ReferenceType (id, TyTy::TyVar (element->get_ref ()),
495+
pattern.get_mutability ());
496+
}
497+
498+
void
499+
ClosureParamInfer::visit (HIR::PathInExpression &pattern)
500+
{
501+
rust_sorry_at (pattern.get_locus (),
502+
"unable to infer this kind of parameter pattern");
503+
}
504+
505+
void
506+
ClosureParamInfer::visit (HIR::StructPattern &pattern)
507+
{
508+
rust_sorry_at (pattern.get_locus (),
509+
"unable to infer this kind of parameter pattern");
510+
}
511+
512+
void
513+
ClosureParamInfer::visit (HIR::TupleStructPattern &pattern)
514+
{
515+
rust_sorry_at (pattern.get_locus (),
516+
"unable to infer this kind of parameter pattern");
517+
}
518+
519+
void
520+
ClosureParamInfer::visit (HIR::TuplePattern &pattern)
521+
{
522+
rust_sorry_at (pattern.get_locus (),
523+
"unable to infer this kind of parameter pattern");
524+
}
525+
526+
void
527+
ClosureParamInfer::visit (HIR::LiteralPattern &pattern)
528+
{
529+
rust_sorry_at (pattern.get_locus (),
530+
"unable to infer this kind of parameter pattern");
531+
}
532+
533+
void
534+
ClosureParamInfer::visit (HIR::RangePattern &pattern)
535+
{
536+
rust_sorry_at (pattern.get_locus (),
537+
"unable to infer this kind of parameter pattern");
538+
}
539+
540+
void
541+
ClosureParamInfer::visit (HIR::QualifiedPathInExpression &pattern)
542+
{
543+
rust_sorry_at (pattern.get_locus (),
544+
"unable to infer this kind of parameter pattern");
545+
}
546+
547+
void
548+
ClosureParamInfer::visit (HIR::SlicePattern &pattern)
549+
{
550+
rust_sorry_at (pattern.get_locus (),
551+
"unable to infer this kind of parameter pattern");
552+
}
553+
554+
void
555+
ClosureParamInfer::visit (HIR::AltPattern &pattern)
556+
{
557+
rust_sorry_at (pattern.get_locus (),
558+
"unable to infer this kind of parameter pattern");
559+
}
560+
450561
} // namespace Resolver
451562
} // namespace Rust

gcc/rust/typecheck/rust-hir-type-check-pattern.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,30 @@ class TypeCheckPattern : public TypeCheckBase, public HIR::HIRPatternVisitor
5858
TyTy::BaseType *infered;
5959
};
6060

61+
class ClosureParamInfer : private TypeCheckBase, private HIR::HIRPatternVisitor
62+
{
63+
public:
64+
static TyTy::BaseType *Resolve (HIR::Pattern *pattern);
65+
66+
void visit (HIR::PathInExpression &pattern) override;
67+
void visit (HIR::StructPattern &pattern) override;
68+
void visit (HIR::TupleStructPattern &pattern) override;
69+
void visit (HIR::WildcardPattern &pattern) override;
70+
void visit (HIR::TuplePattern &pattern) override;
71+
void visit (HIR::LiteralPattern &pattern) override;
72+
void visit (HIR::RangePattern &pattern) override;
73+
void visit (HIR::IdentifierPattern &pattern) override;
74+
void visit (HIR::QualifiedPathInExpression &pattern) override;
75+
void visit (HIR::ReferencePattern &pattern) override;
76+
void visit (HIR::SlicePattern &pattern) override;
77+
void visit (HIR::AltPattern &pattern) override;
78+
79+
private:
80+
ClosureParamInfer ();
81+
82+
TyTy::BaseType *infered;
83+
};
84+
6185
} // namespace Resolver
6286
} // namespace Rust
6387

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#[lang = "fn_once"]
2+
pub trait FnOnce<Args> {
3+
#[lang = "fn_once_output"]
4+
type Output;
5+
6+
extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
7+
}
8+
9+
fn main() {
10+
let lambda = |&c| c != b'9';
11+
12+
let a = b'1';
13+
lambda(&a);
14+
}

0 commit comments

Comments
 (0)