1144: Add name and type resolution support TuplePatterns in MatchArms r=philberty a=philberty

This adds support for the name and type resolution of match expressions. The code generation
and checks for all cases possible cases needs more thought so this will be done as part of a
separate PR.

Addresses #1081 

Co-authored-by: Philip Herron <philip.herron@embecosm.com>
This commit is contained in:
bors[bot] 2022-04-21 17:24:27 +00:00 committed by GitHub
commit cb42c3674a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 507 additions and 247 deletions

View File

@ -2819,12 +2819,7 @@ StructPattern::as_string () const
std::string
LiteralPattern::as_string () const
{
std::string str;
if (has_minus)
str += "-";
return str + lit.as_string ();
return lit.as_string ();
}
std::string

View File

@ -27,14 +27,6 @@ namespace AST {
class LiteralPattern : public Pattern
{
Literal lit;
/* make literal have a type given by enum, etc. rustc uses an extended form of
* its literal token implementation */
// TODO: literal representation - use LiteralExpr? or another thing?
// Minus prefixed to literal (if integer or floating-point)
bool has_minus;
// Actually, this might be a good place to use a template.
Location locus;
NodeId node_id;
@ -42,16 +34,14 @@ public:
std::string as_string () const override;
// Constructor for a literal pattern
LiteralPattern (Literal lit, Location locus, bool has_minus = false)
: lit (std::move (lit)), has_minus (has_minus), locus (locus),
LiteralPattern (Literal lit, Location locus)
: lit (std::move (lit)), locus (locus),
node_id (Analysis::Mappings::get ()->get_next_node_id ())
{}
LiteralPattern (std::string val, Literal::LitType type, Location locus,
bool has_minus = false)
LiteralPattern (std::string val, Literal::LitType type, Location locus)
: lit (Literal (std::move (val), type, PrimitiveCoreType::CORETYPE_STR)),
has_minus (has_minus), locus (locus),
node_id (Analysis::Mappings::get ()->get_next_node_id ())
locus (locus), node_id (Analysis::Mappings::get ()->get_next_node_id ())
{}
Location get_locus () const override final { return locus; }
@ -62,6 +52,10 @@ public:
NodeId get_pattern_node_id () const override final { return node_id; }
Literal &get_literal () { return lit; }
const Literal &get_literal () const { return lit; }
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@ -1110,7 +1104,7 @@ public:
TupleStructPattern (TupleStructPattern &&other) = default;
TupleStructPattern &operator= (TupleStructPattern &&other) = default;
Location get_locus () const { return path.get_locus (); }
Location get_locus () const override { return path.get_locus (); }
void accept_vis (ASTVisitor &vis) override;
@ -1141,6 +1135,12 @@ protected:
class TuplePatternItems
{
public:
enum TuplePatternItemType
{
MULTIPLE,
RANGED,
};
virtual ~TuplePatternItems () {}
// TODO: should this store location data?
@ -1156,6 +1156,8 @@ public:
virtual void accept_vis (ASTVisitor &vis) = 0;
virtual TuplePatternItemType get_pattern_type () const = 0;
protected:
// pure virtual clone implementation
virtual TuplePatternItems *clone_tuple_pattern_items_impl () const = 0;
@ -1240,6 +1242,11 @@ public:
return patterns;
}
TuplePatternItemType get_pattern_type () const override
{
return TuplePatternItemType::MULTIPLE;
}
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@ -1318,6 +1325,11 @@ public:
return upper_patterns;
}
TuplePatternItemType get_pattern_type () const override
{
return TuplePatternItemType::RANGED;
}
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */

View File

@ -183,8 +183,14 @@ protected:
* expression) */
class ExprStmt : public Stmt
{
// TODO: add any useful virtual functions
public:
enum ExprStmtType
{
WITH_BLOCK,
WITHOUT_BLOCK
};
protected:
Location locus;
public:
@ -192,6 +198,8 @@ public:
bool is_item () const override final { return false; }
virtual ExprStmtType get_type () const = 0;
protected:
ExprStmt (Location locus) : locus (locus) {}
};
@ -261,6 +269,11 @@ public:
return expr;
}
ExprStmtType get_type () const override
{
return ExprStmtType::WITHOUT_BLOCK;
};
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@ -328,6 +341,8 @@ public:
bool is_semicolon_followed () const { return semicolon_followed; }
ExprStmtType get_type () const override { return ExprStmtType::WITH_BLOCK; };
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */

View File

@ -18,6 +18,7 @@
#include "rust-ast-lower-base.h"
#include "rust-ast-lower-type.h"
#include "rust-ast-lower-pattern.h"
namespace Rust {
namespace HIR {
@ -885,5 +886,79 @@ ASTLoweringBase::attribute_handled_in_another_pass (
return lookup.handler != Analysis::CompilerPass::HIR_LOWERING;
}
std::unique_ptr<HIR::TuplePatternItems>
ASTLoweringBase::lower_tuple_pattern_multiple (
AST::TuplePatternItemsMultiple &pattern)
{
std::vector<std::unique_ptr<HIR::Pattern> > patterns;
for (auto &p : pattern.get_patterns ())
{
HIR::Pattern *translated = ASTLoweringPattern::translate (p.get ());
patterns.push_back (std::unique_ptr<HIR::Pattern> (translated));
}
return std::unique_ptr<HIR::TuplePatternItems> (
new HIR::TuplePatternItemsMultiple (std::move (patterns)));
}
std::unique_ptr<TuplePatternItems>
ASTLoweringBase::lower_tuple_pattern_ranged (
AST::TuplePatternItemsRanged &pattern)
{
std::vector<std::unique_ptr<HIR::Pattern> > lower_patterns;
std::vector<std::unique_ptr<HIR::Pattern> > upper_patterns;
for (auto &p : pattern.get_lower_patterns ())
{
HIR::Pattern *translated = ASTLoweringPattern::translate (p.get ());
lower_patterns.push_back (std::unique_ptr<HIR::Pattern> (translated));
}
for (auto &p : pattern.get_upper_patterns ())
{
HIR::Pattern *translated = ASTLoweringPattern::translate (p.get ());
upper_patterns.push_back (std::unique_ptr<HIR::Pattern> (translated));
}
return std::unique_ptr<HIR::TuplePatternItems> (
new HIR::TuplePatternItemsRanged (std::move (lower_patterns),
std::move (upper_patterns)));
}
HIR::Literal
ASTLoweringBase::lower_literal (const AST::Literal &literal)
{
HIR::Literal::LitType type = HIR::Literal::LitType::CHAR;
switch (literal.get_lit_type ())
{
case AST::Literal::LitType::CHAR:
type = HIR::Literal::LitType::CHAR;
break;
case AST::Literal::LitType::STRING:
type = HIR::Literal::LitType::STRING;
break;
case AST::Literal::LitType::BYTE:
type = HIR::Literal::LitType::BYTE;
break;
case AST::Literal::LitType::BYTE_STRING:
type = HIR::Literal::LitType::BYTE_STRING;
break;
case AST::Literal::LitType::INT:
type = HIR::Literal::LitType::INT;
break;
case AST::Literal::LitType::FLOAT:
type = HIR::Literal::LitType::FLOAT;
break;
case AST::Literal::LitType::BOOL:
type = HIR::Literal::LitType::BOOL;
break;
case AST::Literal::LitType::ERROR:
gcc_unreachable ();
break;
}
return HIR::Literal (literal.as_string (), type, literal.get_type_hint ());
}
} // namespace HIR
} // namespace Rust

View File

@ -272,6 +272,14 @@ protected:
bool
attribute_handled_in_another_pass (const std::string &attribute_path) const;
std::unique_ptr<TuplePatternItems>
lower_tuple_pattern_multiple (AST::TuplePatternItemsMultiple &pattern);
std::unique_ptr<TuplePatternItems>
lower_tuple_pattern_ranged (AST::TuplePatternItemsRanged &pattern);
HIR::Literal lower_literal (const AST::Literal &literal);
};
} // namespace HIR

View File

@ -327,43 +327,15 @@ public:
void visit (AST::LiteralExpr &expr) override
{
HIR::Literal::LitType type = HIR::Literal::LitType::CHAR;
switch (expr.get_lit_type ())
{
case AST::Literal::LitType::CHAR:
type = HIR::Literal::LitType::CHAR;
break;
case AST::Literal::LitType::STRING:
type = HIR::Literal::LitType::STRING;
break;
case AST::Literal::LitType::BYTE:
type = HIR::Literal::LitType::BYTE;
break;
case AST::Literal::LitType::BYTE_STRING:
type = HIR::Literal::LitType::BYTE_STRING;
break;
case AST::Literal::LitType::INT:
type = HIR::Literal::LitType::INT;
break;
case AST::Literal::LitType::FLOAT:
type = HIR::Literal::LitType::FLOAT;
break;
case AST::Literal::LitType::BOOL:
type = HIR::Literal::LitType::BOOL;
break;
// Error literals should have been stripped during expansion
case AST::Literal::LitType::ERROR:
gcc_unreachable ();
break;
}
auto crate_num = mappings->get_current_crate ();
Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
mappings->get_next_hir_id (crate_num),
UNKNOWN_LOCAL_DEFID);
translated = new HIR::LiteralExpr (mapping, expr.as_string (), type,
expr.get_literal ().get_type_hint (),
expr.get_locus ());
HIR::Literal l = lower_literal (expr.get_literal ());
translated
= new HIR::LiteralExpr (mapping, std::move (l), expr.get_locus (),
expr.get_outer_attrs ());
}
void visit (AST::ArithmeticOrLogicalExpr &expr) override

View File

@ -163,5 +163,50 @@ ASTLoweringPattern::visit (AST::WildcardPattern &pattern)
translated = new HIR::WildcardPattern (mapping, pattern.get_locus ());
}
void
ASTLoweringPattern::visit (AST::TuplePattern &pattern)
{
std::unique_ptr<HIR::TuplePatternItems> items;
switch (pattern.get_items ()->get_pattern_type ())
{
case AST::TuplePatternItems::TuplePatternItemType::MULTIPLE: {
AST::TuplePatternItemsMultiple &ref
= *static_cast<AST::TuplePatternItemsMultiple *> (
pattern.get_items ().get ());
items = lower_tuple_pattern_multiple (ref);
}
break;
case AST::TuplePatternItems::TuplePatternItemType::RANGED: {
AST::TuplePatternItemsRanged &ref
= *static_cast<AST::TuplePatternItemsRanged *> (
pattern.get_items ().get ());
items = lower_tuple_pattern_ranged (ref);
}
break;
}
auto crate_num = mappings->get_current_crate ();
Analysis::NodeMapping mapping (crate_num, pattern.get_node_id (),
mappings->get_next_hir_id (crate_num),
UNKNOWN_LOCAL_DEFID);
translated
= new HIR::TuplePattern (mapping, std::move (items), pattern.get_locus ());
}
void
ASTLoweringPattern::visit (AST::LiteralPattern &pattern)
{
auto crate_num = mappings->get_current_crate ();
Analysis::NodeMapping mapping (crate_num, pattern.get_node_id (),
mappings->get_next_hir_id (crate_num),
UNKNOWN_LOCAL_DEFID);
HIR::Literal l = lower_literal (pattern.get_literal ());
translated
= new HIR::LiteralPattern (mapping, std::move (l), pattern.get_locus ());
}
} // namespace HIR
} // namespace Rust

View File

@ -58,6 +58,10 @@ public:
void visit (AST::WildcardPattern &pattern) override;
void visit (AST::TuplePattern &pattern) override;
void visit (AST::LiteralPattern &pattern) override;
private:
ASTLoweringPattern () : translated (nullptr) {}

View File

@ -77,13 +77,13 @@ public:
LiteralExpr (Analysis::NodeMapping mappings, std::string value_as_string,
Literal::LitType type, PrimitiveCoreType type_hint,
Location locus, AST::AttrVec outer_attrs = AST::AttrVec ())
Location locus, AST::AttrVec outer_attrs)
: ExprWithoutBlock (std::move (mappings), std::move (outer_attrs)),
literal (std::move (value_as_string), type, type_hint), locus (locus)
{}
LiteralExpr (Analysis::NodeMapping mappings, Literal literal, Location locus,
AST::AttrVec outer_attrs = AST::AttrVec ())
AST::AttrVec outer_attrs)
: ExprWithoutBlock (std::move (mappings), std::move (outer_attrs)),
literal (std::move (literal)), locus (locus)
{}

View File

@ -2589,14 +2589,7 @@ StructPattern::as_string () const
std::string
LiteralPattern::as_string () const
{
std::string str;
if (has_minus)
{
str += "-";
}
return str + lit.as_string ();
return lit.as_string ();
}
std::string

View File

@ -29,7 +29,6 @@ namespace HIR {
class LiteralPattern : public Pattern
{
Literal lit;
bool has_minus;
Location locus;
Analysis::NodeMapping mappings;
@ -37,16 +36,14 @@ public:
std::string as_string () const override;
// Constructor for a literal pattern
LiteralPattern (Analysis::NodeMapping mappings, Literal lit, Location locus,
bool has_minus = false)
: lit (std::move (lit)), has_minus (has_minus), locus (locus),
mappings (mappings)
LiteralPattern (Analysis::NodeMapping mappings, Literal lit, Location locus)
: lit (std::move (lit)), locus (locus), mappings (mappings)
{}
LiteralPattern (Analysis::NodeMapping mappings, std::string val,
Literal::LitType type, Location locus, bool has_minus = false)
Literal::LitType type, Location locus)
: lit (Literal (std::move (val), type, PrimitiveCoreType::CORETYPE_STR)),
has_minus (has_minus), locus (locus), mappings (mappings)
locus (locus), mappings (mappings)
{}
Location get_locus () const override { return locus; }
@ -64,6 +61,9 @@ public:
return PatternType::LITERAL;
}
Literal &get_literal () { return lit; }
const Literal &get_literal () const { return lit; }
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@ -962,6 +962,12 @@ protected:
class TuplePatternItems
{
public:
enum TuplePatternItemType
{
MULTIPLE,
RANGED,
};
virtual ~TuplePatternItems () {}
// TODO: should this store location data?
@ -977,6 +983,8 @@ public:
virtual void accept_vis (HIRFullVisitor &vis) = 0;
virtual TuplePatternItemType get_pattern_type () const = 0;
protected:
// pure virtual clone implementation
virtual TuplePatternItems *clone_tuple_pattern_items_impl () const = 0;
@ -1019,6 +1027,17 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
TuplePatternItemType get_pattern_type () const override
{
return TuplePatternItemType::MULTIPLE;
}
std::vector<std::unique_ptr<Pattern> > &get_patterns () { return patterns; }
const std::vector<std::unique_ptr<Pattern> > &get_patterns () const
{
return patterns;
}
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@ -1077,6 +1096,11 @@ public:
void accept_vis (HIRFullVisitor &vis) override;
TuplePatternItemType get_pattern_type () const override
{
return TuplePatternItemType::RANGED;
}
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@ -1135,6 +1159,9 @@ public:
return PatternType::TUPLE;
}
std::unique_ptr<TuplePatternItems> &get_items () { return items; }
const std::unique_ptr<TuplePatternItems> &get_items () const { return items; }
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */

View File

@ -8563,7 +8563,11 @@ Parser<ManagedTokenSource>::parse_match_expr (AST::AttrVec outer_attrs,
return nullptr;
}
std::unique_ptr<AST::Expr> expr = parse_expr ();
ParseRestrictions restrictions;
restrictions.expr_can_be_stmt = true;
restrictions.consume_semi = false;
std::unique_ptr<AST::ExprStmt> expr = parse_expr_stmt ({}, restrictions);
if (expr == nullptr)
{
Error error (lexer.peek_token ()->get_locus (),
@ -8573,10 +8577,30 @@ Parser<ManagedTokenSource>::parse_match_expr (AST::AttrVec outer_attrs,
// skip somewhere?
return nullptr;
}
bool is_expr_without_block = expr->is_expr_without_block ();
bool is_expr_without_block
= expr->get_type () == AST::ExprStmt::ExprStmtType::WITHOUT_BLOCK;
// construct match case expr and add to cases
match_arms.push_back (AST::MatchCase (std::move (arm), std::move (expr)));
switch (expr->get_type ())
{
case AST::ExprStmt::ExprStmtType::WITH_BLOCK: {
AST::ExprStmtWithBlock *cast
= static_cast<AST::ExprStmtWithBlock *> (expr.get ());
std::unique_ptr<AST::Expr> e = cast->get_expr ()->clone_expr ();
match_arms.push_back (
AST::MatchCase (std::move (arm), std::move (e)));
}
break;
case AST::ExprStmt::ExprStmtType::WITHOUT_BLOCK: {
AST::ExprStmtWithoutBlock *cast
= static_cast<AST::ExprStmtWithoutBlock *> (expr.get ());
std::unique_ptr<AST::Expr> e = cast->get_expr ()->clone_expr ();
match_arms.push_back (
AST::MatchCase (std::move (arm), std::move (e)));
}
break;
}
// handle comma presence
if (lexer.peek_token ()->get_id () != COMMA)
@ -10400,7 +10424,7 @@ Parser<ManagedTokenSource>::parse_literal_or_range_pattern ()
// literal pattern
return std::unique_ptr<AST::LiteralPattern> (
new AST::LiteralPattern (range_lower->get_str (), type,
range_lower->get_locus (), has_minus));
range_lower->get_locus ()));
}
}

View File

@ -100,5 +100,35 @@ PatternDeclaration::visit (AST::StructPattern &pattern)
rust_assert (!struct_pattern_elems.has_etc ());
}
void
PatternDeclaration::visit (AST::TuplePattern &pattern)
{
std::unique_ptr<AST::TuplePatternItems> &items = pattern.get_items ();
switch (items->get_pattern_type ())
{
case AST::TuplePatternItems::TuplePatternItemType::MULTIPLE: {
AST::TuplePatternItemsMultiple &ref
= *static_cast<AST::TuplePatternItemsMultiple *> (
pattern.get_items ().get ());
for (auto &p : ref.get_patterns ())
p->accept_vis (*this);
}
break;
case AST::TuplePatternItems::TuplePatternItemType::RANGED: {
AST::TuplePatternItemsRanged &ref
= *static_cast<AST::TuplePatternItemsRanged *> (
pattern.get_items ().get ());
for (auto &p : ref.get_lower_patterns ())
p->accept_vis (*this);
for (auto &p : ref.get_upper_patterns ())
p->accept_vis (*this);
}
break;
}
}
} // namespace Resolver
} // namespace Rust

View File

@ -101,6 +101,8 @@ public:
void visit (AST::TupleStructPattern &pattern) override;
void visit (AST::TuplePattern &pattern) override;
private:
PatternDeclaration (NodeId parent) : ResolverBase (parent) {}
};

View File

@ -80,5 +80,177 @@ TypeCheckBase::check_for_unconstrained (
return unconstrained;
}
TyTy::BaseType *
TypeCheckBase::resolve_literal (const Analysis::NodeMapping &expr_mappings,
HIR::Literal &literal, Location locus)
{
TyTy::BaseType *infered = nullptr;
switch (literal.get_lit_type ())
{
case HIR::Literal::LitType::INT: {
bool ok = false;
switch (literal.get_type_hint ())
{
case CORETYPE_I8:
ok = context->lookup_builtin ("i8", &infered);
break;
case CORETYPE_I16:
ok = context->lookup_builtin ("i16", &infered);
break;
case CORETYPE_I32:
ok = context->lookup_builtin ("i32", &infered);
break;
case CORETYPE_I64:
ok = context->lookup_builtin ("i64", &infered);
break;
case CORETYPE_I128:
ok = context->lookup_builtin ("i128", &infered);
break;
case CORETYPE_U8:
ok = context->lookup_builtin ("u8", &infered);
break;
case CORETYPE_U16:
ok = context->lookup_builtin ("u16", &infered);
break;
case CORETYPE_U32:
ok = context->lookup_builtin ("u32", &infered);
break;
case CORETYPE_U64:
ok = context->lookup_builtin ("u64", &infered);
break;
case CORETYPE_U128:
ok = context->lookup_builtin ("u128", &infered);
break;
case CORETYPE_F32:
literal.set_lit_type (HIR::Literal::LitType::FLOAT);
ok = context->lookup_builtin ("f32", &infered);
break;
case CORETYPE_F64:
literal.set_lit_type (HIR::Literal::LitType::FLOAT);
ok = context->lookup_builtin ("f64", &infered);
break;
default:
ok = true;
infered
= new TyTy::InferType (expr_mappings.get_hirid (),
TyTy::InferType::InferTypeKind::INTEGRAL,
locus);
break;
}
rust_assert (ok);
}
break;
case HIR::Literal::LitType::FLOAT: {
bool ok = false;
switch (literal.get_type_hint ())
{
case CORETYPE_F32:
ok = context->lookup_builtin ("f32", &infered);
break;
case CORETYPE_F64:
ok = context->lookup_builtin ("f64", &infered);
break;
default:
ok = true;
infered
= new TyTy::InferType (expr_mappings.get_hirid (),
TyTy::InferType::InferTypeKind::FLOAT,
locus);
break;
}
rust_assert (ok);
}
break;
case HIR::Literal::LitType::BOOL: {
auto ok = context->lookup_builtin ("bool", &infered);
rust_assert (ok);
}
break;
case HIR::Literal::LitType::CHAR: {
auto ok = context->lookup_builtin ("char", &infered);
rust_assert (ok);
}
break;
case HIR::Literal::LitType::BYTE: {
auto ok = context->lookup_builtin ("u8", &infered);
rust_assert (ok);
}
break;
case HIR::Literal::LitType::STRING: {
TyTy::BaseType *base = nullptr;
auto ok = context->lookup_builtin ("str", &base);
rust_assert (ok);
infered = new TyTy::ReferenceType (expr_mappings.get_hirid (),
TyTy::TyVar (base->get_ref ()),
Mutability::Imm);
}
break;
case HIR::Literal::LitType::BYTE_STRING: {
/* This is an arraytype of u8 reference (&[u8;size]). It isn't in
UTF-8, but really just a byte array. Code to construct the array
reference copied from ArrayElemsValues and ArrayType. */
TyTy::BaseType *u8;
auto ok = context->lookup_builtin ("u8", &u8);
rust_assert (ok);
auto crate_num = mappings->get_current_crate ();
Analysis::NodeMapping capacity_mapping (crate_num, UNKNOWN_NODEID,
mappings->get_next_hir_id (
crate_num),
UNKNOWN_LOCAL_DEFID);
/* Capacity is the size of the string (number of chars).
It is a constant, but for fold it to get a tree. */
std::string capacity_str
= std::to_string (literal.as_string ().size ());
HIR::LiteralExpr *literal_capacity
= new HIR::LiteralExpr (capacity_mapping, capacity_str,
HIR::Literal::LitType::INT,
PrimitiveCoreType::CORETYPE_USIZE, locus, {});
// mark the type for this implicit node
TyTy::BaseType *expected_ty = nullptr;
ok = context->lookup_builtin ("usize", &expected_ty);
rust_assert (ok);
context->insert_type (capacity_mapping, expected_ty);
Analysis::NodeMapping array_mapping (crate_num, UNKNOWN_NODEID,
mappings->get_next_hir_id (
crate_num),
UNKNOWN_LOCAL_DEFID);
TyTy::ArrayType *array
= new TyTy::ArrayType (array_mapping.get_hirid (), locus,
*literal_capacity,
TyTy::TyVar (u8->get_ref ()));
context->insert_type (array_mapping, array);
infered = new TyTy::ReferenceType (expr_mappings.get_hirid (),
TyTy::TyVar (array->get_ref ()),
Mutability::Imm);
}
break;
default:
gcc_unreachable ();
break;
}
return infered;
}
} // namespace Resolver
} // namespace Rust

View File

@ -55,6 +55,9 @@ protected:
const TyTy::SubstitutionArgumentMappings &constraint_b,
const TyTy::BaseType *reference);
TyTy::BaseType *resolve_literal (const Analysis::NodeMapping &mappings,
HIR::Literal &literal, Location locus);
Analysis::Mappings *mappings;
Resolver *resolver;
TypeCheckContext *context;

View File

@ -57,7 +57,7 @@ public:
= new HIR::LiteralExpr (mapping, std::to_string (last_discriminant),
HIR::Literal::LitType::INT,
PrimitiveCoreType::CORETYPE_I64,
item.get_locus ());
item.get_locus (), {});
TyTy::BaseType *isize = nullptr;
bool ok = context->lookup_builtin ("isize", &isize);
@ -135,7 +135,7 @@ public:
= new HIR::LiteralExpr (mapping, std::to_string (last_discriminant),
HIR::Literal::LitType::INT,
PrimitiveCoreType::CORETYPE_I64,
item.get_locus ());
item.get_locus (), {});
TyTy::BaseType *isize = nullptr;
bool ok = context->lookup_builtin ("isize", &isize);
@ -182,7 +182,7 @@ public:
= new HIR::LiteralExpr (mapping, std::to_string (last_discriminant),
HIR::Literal::LitType::INT,
PrimitiveCoreType::CORETYPE_I64,
item.get_locus ());
item.get_locus (), {});
TyTy::BaseType *isize = nullptr;
bool ok = context->lookup_builtin ("isize", &isize);

View File

@ -535,172 +535,8 @@ public:
void visit (HIR::LiteralExpr &expr) override
{
switch (expr.get_lit_type ())
{
case HIR::Literal::LitType::INT: {
bool ok = false;
switch (expr.get_literal ().get_type_hint ())
{
case CORETYPE_I8:
ok = context->lookup_builtin ("i8", &infered);
break;
case CORETYPE_I16:
ok = context->lookup_builtin ("i16", &infered);
break;
case CORETYPE_I32:
ok = context->lookup_builtin ("i32", &infered);
break;
case CORETYPE_I64:
ok = context->lookup_builtin ("i64", &infered);
break;
case CORETYPE_I128:
ok = context->lookup_builtin ("i128", &infered);
break;
case CORETYPE_U8:
ok = context->lookup_builtin ("u8", &infered);
break;
case CORETYPE_U16:
ok = context->lookup_builtin ("u16", &infered);
break;
case CORETYPE_U32:
ok = context->lookup_builtin ("u32", &infered);
break;
case CORETYPE_U64:
ok = context->lookup_builtin ("u64", &infered);
break;
case CORETYPE_U128:
ok = context->lookup_builtin ("u128", &infered);
break;
case CORETYPE_F32:
expr.get_literal ().set_lit_type (HIR::Literal::LitType::FLOAT);
ok = context->lookup_builtin ("f32", &infered);
break;
case CORETYPE_F64:
expr.get_literal ().set_lit_type (HIR::Literal::LitType::FLOAT);
ok = context->lookup_builtin ("f64", &infered);
break;
default:
ok = true;
infered
= new TyTy::InferType (expr.get_mappings ().get_hirid (),
TyTy::InferType::InferTypeKind::INTEGRAL,
expr.get_locus ());
break;
}
rust_assert (ok);
}
break;
case HIR::Literal::LitType::FLOAT: {
bool ok = false;
switch (expr.get_literal ().get_type_hint ())
{
case CORETYPE_F32:
ok = context->lookup_builtin ("f32", &infered);
break;
case CORETYPE_F64:
ok = context->lookup_builtin ("f64", &infered);
break;
default:
ok = true;
infered
= new TyTy::InferType (expr.get_mappings ().get_hirid (),
TyTy::InferType::InferTypeKind::FLOAT,
expr.get_locus ());
break;
}
rust_assert (ok);
}
break;
case HIR::Literal::LitType::BOOL: {
auto ok = context->lookup_builtin ("bool", &infered);
rust_assert (ok);
}
break;
case HIR::Literal::LitType::CHAR: {
auto ok = context->lookup_builtin ("char", &infered);
rust_assert (ok);
}
break;
case HIR::Literal::LitType::BYTE: {
auto ok = context->lookup_builtin ("u8", &infered);
rust_assert (ok);
}
break;
case HIR::Literal::LitType::STRING: {
TyTy::BaseType *base = nullptr;
auto ok = context->lookup_builtin ("str", &base);
rust_assert (ok);
infered = new TyTy::ReferenceType (expr.get_mappings ().get_hirid (),
TyTy::TyVar (base->get_ref ()),
Mutability::Imm);
}
break;
case HIR::Literal::LitType::BYTE_STRING: {
/* This is an arraytype of u8 reference (&[u8;size]). It isn't in
UTF-8, but really just a byte array. Code to construct the array
reference copied from ArrayElemsValues and ArrayType. */
TyTy::BaseType *u8;
auto ok = context->lookup_builtin ("u8", &u8);
rust_assert (ok);
auto crate_num = mappings->get_current_crate ();
Analysis::NodeMapping capacity_mapping (crate_num, UNKNOWN_NODEID,
mappings->get_next_hir_id (
crate_num),
UNKNOWN_LOCAL_DEFID);
/* Capacity is the size of the string (number of chars).
It is a constant, but for fold it to get a tree. */
std::string capacity_str
= std::to_string (expr.get_literal ().as_string ().size ());
HIR::LiteralExpr *literal_capacity
= new HIR::LiteralExpr (capacity_mapping, capacity_str,
HIR::Literal::LitType::INT,
PrimitiveCoreType::CORETYPE_USIZE,
expr.get_locus ());
// mark the type for this implicit node
TyTy::BaseType *expected_ty = nullptr;
ok = context->lookup_builtin ("usize", &expected_ty);
rust_assert (ok);
context->insert_type (capacity_mapping, expected_ty);
Analysis::NodeMapping array_mapping (crate_num, UNKNOWN_NODEID,
mappings->get_next_hir_id (
crate_num),
UNKNOWN_LOCAL_DEFID);
TyTy::ArrayType *array
= new TyTy::ArrayType (array_mapping.get_hirid (),
expr.get_locus (), *literal_capacity,
TyTy::TyVar (u8->get_ref ()));
context->insert_type (array_mapping, array);
infered = new TyTy::ReferenceType (expr.get_mappings ().get_hirid (),
TyTy::TyVar (array->get_ref ()),
Mutability::Imm);
}
break;
default:
gcc_unreachable ();
break;
}
infered = infered->clone ();
infered = resolve_literal (expr.get_mappings (), expr.get_literal (),
expr.get_locus ());
}
void visit (HIR::ArithmeticOrLogicalExpr &expr) override
@ -929,7 +765,7 @@ public:
= new HIR::LiteralExpr (mapping, capacity_str,
HIR::Literal::LitType::INT,
PrimitiveCoreType::CORETYPE_USIZE,
Location ());
Location (), {});
// mark the type for this implicit node
TyTy::BaseType *expected_ty = nullptr;

View File

@ -232,5 +232,46 @@ TypeCheckPattern::visit (HIR::WildcardPattern &pattern)
infered->set_ref (pattern.get_pattern_mappings ().get_hirid ());
}
void
TypeCheckPattern::visit (HIR::TuplePattern &pattern)
{
std::unique_ptr<HIR::TuplePatternItems> items;
switch (pattern.get_items ()->get_pattern_type ())
{
case HIR::TuplePatternItems::TuplePatternItemType::MULTIPLE: {
HIR::TuplePatternItemsMultiple &ref
= *static_cast<HIR::TuplePatternItemsMultiple *> (
pattern.get_items ().get ());
std::vector<TyTy::TyVar> pattern_elems;
for (auto &p : ref.get_patterns ())
{
TyTy::BaseType *elem = TypeCheckPattern::Resolve (p.get (), parent);
pattern_elems.push_back (TyTy::TyVar (elem->get_ref ()));
}
infered
= new TyTy::TupleType (pattern.get_pattern_mappings ().get_hirid (),
pattern.get_locus (), pattern_elems);
}
break;
case HIR::TuplePatternItems::TuplePatternItemType::RANGED: {
// HIR::TuplePatternItemsRanged &ref
// = *static_cast<HIR::TuplePatternItemsRanged *> (
// pattern.get_items ().get ());
// TODO
gcc_unreachable ();
}
break;
}
}
void
TypeCheckPattern::visit (HIR::LiteralPattern &pattern)
{
infered = resolve_literal (pattern.get_pattern_mappings (),
pattern.get_literal (), pattern.get_locus ());
}
} // namespace Resolver
} // namespace Rust

View File

@ -39,6 +39,8 @@ public:
return new TyTy::ErrorType (
pattern->get_pattern_mappings ().get_hirid ());
resolver.context->insert_type (pattern->get_pattern_mappings (),
resolver.infered);
return resolver.infered;
}
@ -50,13 +52,17 @@ public:
void visit (HIR::WildcardPattern &pattern) override;
void visit (HIR::TuplePattern &pattern) override;
void visit (HIR::LiteralPattern &pattern) override;
private:
TypeCheckPattern (TyTy::BaseType *parent)
: TypeCheckBase (), infered (nullptr), parent (parent)
: TypeCheckBase (), parent (parent), infered (nullptr)
{}
TyTy::BaseType *infered;
TyTy::BaseType *parent;
TyTy::BaseType *infered;
};
} // namespace Resolver