mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-20 19:01:12 +08:00
gccrs: Add declarations for Rust HIR
This patch contains the declarations needed for our second intermediate representation, which we will refer to as an HIR. This gives the front-end a chance to desugar much of the AST, such as: - Removing distinction between functions and methods - Removing Macros - Removing IdentifierExprs - Removing duplicate attribute structures gcc/rust/ * hir/tree/rust-hir-expr.h: New. * hir/tree/rust-hir-item.h: New. * hir/tree/rust-hir-path.h: New. * hir/tree/rust-hir-pattern.h: New. * hir/tree/rust-hir-stmt.h: New. * hir/tree/rust-hir-type.h: New.
This commit is contained in:
parent
85a8fe00f8
commit
8ad1d56d68
4194
gcc/rust/hir/tree/rust-hir-expr.h
Normal file
4194
gcc/rust/hir/tree/rust-hir-expr.h
Normal file
File diff suppressed because it is too large
Load Diff
3207
gcc/rust/hir/tree/rust-hir-item.h
Normal file
3207
gcc/rust/hir/tree/rust-hir-item.h
Normal file
File diff suppressed because it is too large
Load Diff
1013
gcc/rust/hir/tree/rust-hir-path.h
Normal file
1013
gcc/rust/hir/tree/rust-hir-path.h
Normal file
File diff suppressed because it is too large
Load Diff
1356
gcc/rust/hir/tree/rust-hir-pattern.h
Normal file
1356
gcc/rust/hir/tree/rust-hir-pattern.h
Normal file
File diff suppressed because it is too large
Load Diff
273
gcc/rust/hir/tree/rust-hir-stmt.h
Normal file
273
gcc/rust/hir/tree/rust-hir-stmt.h
Normal file
@ -0,0 +1,273 @@
|
||||
// Copyright (C) 2020-2022 Free Software Foundation, Inc.
|
||||
|
||||
// This file is part of GCC.
|
||||
|
||||
// GCC is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation; either version 3, or (at your option) any later
|
||||
// version.
|
||||
|
||||
// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
// for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with GCC; see the file COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef RUST_HIR_STATEMENT_H
|
||||
#define RUST_HIR_STATEMENT_H
|
||||
|
||||
#include "rust-hir.h"
|
||||
#include "rust-hir-path.h"
|
||||
#include "rust-hir-expr.h"
|
||||
|
||||
namespace Rust {
|
||||
namespace HIR {
|
||||
// Just a semi-colon, which apparently is a statement.
|
||||
class EmptyStmt : public Stmt
|
||||
{
|
||||
Location locus;
|
||||
|
||||
public:
|
||||
std::string as_string () const override { return std::string (1, ';'); }
|
||||
|
||||
EmptyStmt (Analysis::NodeMapping mappings, Location locus)
|
||||
: Stmt (std::move (mappings)), locus (locus)
|
||||
{}
|
||||
|
||||
Location get_locus () const override final { return locus; }
|
||||
|
||||
void accept_vis (HIRFullVisitor &vis) override;
|
||||
void accept_vis (HIRStmtVisitor &vis) override;
|
||||
|
||||
bool is_item () const override final { return false; }
|
||||
|
||||
protected:
|
||||
/* Use covariance to implement clone function as returning this object rather
|
||||
* than base */
|
||||
EmptyStmt *clone_stmt_impl () const override { return new EmptyStmt (*this); }
|
||||
};
|
||||
|
||||
/* Variable assignment let statement - type of "declaration statement" as it
|
||||
* introduces new name into scope */
|
||||
class LetStmt : public Stmt
|
||||
{
|
||||
// bool has_outer_attrs;
|
||||
AST::AttrVec outer_attrs;
|
||||
|
||||
std::unique_ptr<Pattern> variables_pattern;
|
||||
|
||||
// bool has_type;
|
||||
std::unique_ptr<Type> type;
|
||||
|
||||
// bool has_init_expr;
|
||||
std::unique_ptr<Expr> init_expr;
|
||||
|
||||
Location locus;
|
||||
|
||||
public:
|
||||
// Returns whether let statement has outer attributes.
|
||||
bool has_outer_attrs () const { return !outer_attrs.empty (); }
|
||||
|
||||
// Returns whether let statement has a given return type.
|
||||
bool has_type () const { return type != nullptr; }
|
||||
|
||||
// Returns whether let statement has an initialisation expression.
|
||||
bool has_init_expr () const { return init_expr != nullptr; }
|
||||
|
||||
std::string as_string () const override;
|
||||
|
||||
LetStmt (Analysis::NodeMapping mappings,
|
||||
std::unique_ptr<Pattern> variables_pattern,
|
||||
std::unique_ptr<Expr> init_expr, std::unique_ptr<Type> type,
|
||||
AST::AttrVec outer_attrs, Location locus)
|
||||
: Stmt (std::move (mappings)), outer_attrs (std::move (outer_attrs)),
|
||||
variables_pattern (std::move (variables_pattern)),
|
||||
type (std::move (type)), init_expr (std::move (init_expr)), locus (locus)
|
||||
{}
|
||||
|
||||
// Copy constructor with clone
|
||||
LetStmt (LetStmt const &other)
|
||||
: Stmt (other.mappings), outer_attrs (other.outer_attrs),
|
||||
locus (other.locus)
|
||||
{
|
||||
// guard to prevent null dereference (only required if error state)
|
||||
if (other.variables_pattern != nullptr)
|
||||
variables_pattern = other.variables_pattern->clone_pattern ();
|
||||
|
||||
// guard to prevent null dereference (always required)
|
||||
if (other.init_expr != nullptr)
|
||||
init_expr = other.init_expr->clone_expr ();
|
||||
if (other.type != nullptr)
|
||||
type = other.type->clone_type ();
|
||||
}
|
||||
|
||||
// Overloaded assignment operator to clone
|
||||
LetStmt &operator= (LetStmt const &other)
|
||||
{
|
||||
outer_attrs = other.outer_attrs;
|
||||
locus = other.locus;
|
||||
|
||||
// guard to prevent null dereference (only required if error state)
|
||||
if (other.variables_pattern != nullptr)
|
||||
variables_pattern = other.variables_pattern->clone_pattern ();
|
||||
else
|
||||
variables_pattern = nullptr;
|
||||
|
||||
// guard to prevent null dereference (always required)
|
||||
if (other.init_expr != nullptr)
|
||||
init_expr = other.init_expr->clone_expr ();
|
||||
else
|
||||
init_expr = nullptr;
|
||||
if (other.type != nullptr)
|
||||
type = other.type->clone_type ();
|
||||
else
|
||||
type = nullptr;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// move constructors
|
||||
LetStmt (LetStmt &&other) = default;
|
||||
LetStmt &operator= (LetStmt &&other) = default;
|
||||
|
||||
Location get_locus () const override final { return locus; }
|
||||
|
||||
void accept_vis (HIRFullVisitor &vis) override;
|
||||
void accept_vis (HIRStmtVisitor &vis) override;
|
||||
|
||||
HIR::Type *get_type () { return type.get (); }
|
||||
|
||||
HIR::Expr *get_init_expr () { return init_expr.get (); }
|
||||
|
||||
HIR::Pattern *get_pattern () { return variables_pattern.get (); }
|
||||
|
||||
bool is_item () const override final { return false; }
|
||||
|
||||
protected:
|
||||
/* Use covariance to implement clone function as returning this object rather
|
||||
* than base */
|
||||
LetStmt *clone_stmt_impl () const override { return new LetStmt (*this); }
|
||||
};
|
||||
|
||||
/* Abstract base class for expression statements (statements containing an
|
||||
* expression) */
|
||||
class ExprStmt : public Stmt
|
||||
{
|
||||
// TODO: add any useful virtual functions
|
||||
|
||||
Location locus;
|
||||
|
||||
public:
|
||||
Location get_locus () const override final { return locus; }
|
||||
|
||||
bool is_item () const override final { return false; }
|
||||
|
||||
protected:
|
||||
ExprStmt (Analysis::NodeMapping mappings, Location locus)
|
||||
: Stmt (std::move (mappings)), locus (locus)
|
||||
{}
|
||||
};
|
||||
|
||||
/* Statement containing an expression without a block (or, due to technical
|
||||
* difficulties, can only be guaranteed to hold an expression). */
|
||||
class ExprStmtWithoutBlock : public ExprStmt
|
||||
{
|
||||
std::unique_ptr<Expr> expr;
|
||||
|
||||
public:
|
||||
std::string as_string () const override;
|
||||
|
||||
ExprStmtWithoutBlock (Analysis::NodeMapping mappings,
|
||||
std::unique_ptr<Expr> expr, Location locus)
|
||||
: ExprStmt (std::move (mappings), locus), expr (std::move (expr))
|
||||
{}
|
||||
|
||||
// Copy constructor with clone
|
||||
ExprStmtWithoutBlock (ExprStmtWithoutBlock const &other)
|
||||
: ExprStmt (other), expr (other.expr->clone_expr ())
|
||||
{}
|
||||
|
||||
// Overloaded assignment operator to clone
|
||||
ExprStmtWithoutBlock &operator= (ExprStmtWithoutBlock const &other)
|
||||
{
|
||||
ExprStmt::operator= (other);
|
||||
expr = other.expr->clone_expr ();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// move constructors
|
||||
ExprStmtWithoutBlock (ExprStmtWithoutBlock &&other) = default;
|
||||
ExprStmtWithoutBlock &operator= (ExprStmtWithoutBlock &&other) = default;
|
||||
|
||||
void accept_vis (HIRFullVisitor &vis) override;
|
||||
void accept_vis (HIRStmtVisitor &vis) override;
|
||||
|
||||
Expr *get_expr () { return expr.get (); }
|
||||
|
||||
protected:
|
||||
/* Use covariance to implement clone function as returning this object rather
|
||||
* than base */
|
||||
ExprStmtWithoutBlock *clone_stmt_impl () const override
|
||||
{
|
||||
return new ExprStmtWithoutBlock (*this);
|
||||
}
|
||||
};
|
||||
|
||||
// Statement containing an expression with a block
|
||||
class ExprStmtWithBlock : public ExprStmt
|
||||
{
|
||||
std::unique_ptr<ExprWithBlock> expr;
|
||||
bool must_be_unit;
|
||||
|
||||
public:
|
||||
std::string as_string () const override;
|
||||
|
||||
ExprStmtWithBlock (Analysis::NodeMapping mappings,
|
||||
std::unique_ptr<ExprWithBlock> expr, Location locus,
|
||||
bool must_be_unit)
|
||||
: ExprStmt (std::move (mappings), locus), expr (std::move (expr)),
|
||||
must_be_unit (must_be_unit)
|
||||
{}
|
||||
|
||||
// Copy constructor with clone
|
||||
ExprStmtWithBlock (ExprStmtWithBlock const &other)
|
||||
: ExprStmt (other), expr (other.expr->clone_expr_with_block ())
|
||||
{}
|
||||
|
||||
// Overloaded assignment operator to clone
|
||||
ExprStmtWithBlock &operator= (ExprStmtWithBlock const &other)
|
||||
{
|
||||
ExprStmt::operator= (other);
|
||||
expr = other.expr->clone_expr_with_block ();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// move constructors
|
||||
ExprStmtWithBlock (ExprStmtWithBlock &&other) = default;
|
||||
ExprStmtWithBlock &operator= (ExprStmtWithBlock &&other) = default;
|
||||
|
||||
void accept_vis (HIRFullVisitor &vis) override;
|
||||
void accept_vis (HIRStmtVisitor &vis) override;
|
||||
|
||||
ExprWithBlock *get_expr () { return expr.get (); }
|
||||
|
||||
bool is_unit_check_needed () const override { return must_be_unit; }
|
||||
|
||||
protected:
|
||||
/* Use covariance to implement clone function as returning this object rather
|
||||
* than base */
|
||||
ExprStmtWithBlock *clone_stmt_impl () const override
|
||||
{
|
||||
return new ExprStmtWithBlock (*this);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace HIR
|
||||
} // namespace Rust
|
||||
|
||||
#endif
|
860
gcc/rust/hir/tree/rust-hir-type.h
Normal file
860
gcc/rust/hir/tree/rust-hir-type.h
Normal file
@ -0,0 +1,860 @@
|
||||
// Copyright (C) 2020-2022 Free Software Foundation, Inc.
|
||||
|
||||
// This file is part of GCC.
|
||||
|
||||
// GCC is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation; either version 3, or (at your option) any later
|
||||
// version.
|
||||
|
||||
// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
// for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with GCC; see the file COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef RUST_HIR_TYPE_H
|
||||
#define RUST_HIR_TYPE_H
|
||||
|
||||
#include "rust-common.h"
|
||||
#include "rust-hir.h"
|
||||
#include "rust-hir-path.h"
|
||||
|
||||
namespace Rust {
|
||||
namespace HIR {
|
||||
// definitions moved to rust-ast.h
|
||||
class TypeParamBound;
|
||||
class Lifetime;
|
||||
|
||||
// A trait bound
|
||||
class TraitBound : public TypeParamBound
|
||||
{
|
||||
bool in_parens;
|
||||
bool opening_question_mark;
|
||||
std::vector<LifetimeParam> for_lifetimes;
|
||||
TypePath type_path;
|
||||
Location locus;
|
||||
|
||||
Analysis::NodeMapping mappings;
|
||||
|
||||
public:
|
||||
// Returns whether trait bound has "for" lifetimes
|
||||
bool has_for_lifetimes () const { return !for_lifetimes.empty (); }
|
||||
|
||||
TraitBound (Analysis::NodeMapping mapping, TypePath type_path, Location locus,
|
||||
bool in_parens = false, bool opening_question_mark = false,
|
||||
std::vector<LifetimeParam> for_lifetimes
|
||||
= std::vector<LifetimeParam> ())
|
||||
: in_parens (in_parens), opening_question_mark (opening_question_mark),
|
||||
for_lifetimes (std::move (for_lifetimes)),
|
||||
type_path (std::move (type_path)), locus (locus), mappings (mapping)
|
||||
{}
|
||||
|
||||
std::string as_string () const override;
|
||||
|
||||
Location get_locus () const override final { return locus; }
|
||||
|
||||
void accept_vis (HIRFullVisitor &vis) override;
|
||||
|
||||
Analysis::NodeMapping get_mappings () const override final
|
||||
{
|
||||
return mappings;
|
||||
}
|
||||
|
||||
BoundType get_bound_type () const final override { return TRAITBOUND; }
|
||||
|
||||
TypePath &get_path () { return type_path; }
|
||||
|
||||
const TypePath &get_path () const { return type_path; }
|
||||
|
||||
protected:
|
||||
/* Use covariance to implement clone function as returning this object rather
|
||||
* than base */
|
||||
TraitBound *clone_type_param_bound_impl () const override
|
||||
{
|
||||
return new TraitBound (*this);
|
||||
}
|
||||
};
|
||||
|
||||
// definition moved to rust-ast.h
|
||||
class TypeNoBounds;
|
||||
|
||||
// An impl trait? Poor reference material here.
|
||||
class ImplTraitType : public Type
|
||||
{
|
||||
// TypeParamBounds type_param_bounds;
|
||||
// inlined form
|
||||
std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds;
|
||||
|
||||
protected:
|
||||
/* Use covariance to implement clone function as returning this object rather
|
||||
* than base */
|
||||
ImplTraitType *clone_type_impl () const override
|
||||
{
|
||||
return new ImplTraitType (*this);
|
||||
}
|
||||
|
||||
public:
|
||||
ImplTraitType (Analysis::NodeMapping mappings,
|
||||
std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
|
||||
Location locus)
|
||||
: Type (mappings, locus), type_param_bounds (std::move (type_param_bounds))
|
||||
{}
|
||||
|
||||
// copy constructor with vector clone
|
||||
ImplTraitType (ImplTraitType const &other)
|
||||
: Type (other.mappings, other.locus)
|
||||
{
|
||||
type_param_bounds.reserve (other.type_param_bounds.size ());
|
||||
for (const auto &e : other.type_param_bounds)
|
||||
type_param_bounds.push_back (e->clone_type_param_bound ());
|
||||
}
|
||||
|
||||
// overloaded assignment operator to clone
|
||||
ImplTraitType &operator= (ImplTraitType const &other)
|
||||
{
|
||||
locus = other.locus;
|
||||
mappings = other.mappings;
|
||||
|
||||
type_param_bounds.reserve (other.type_param_bounds.size ());
|
||||
for (const auto &e : other.type_param_bounds)
|
||||
type_param_bounds.push_back (e->clone_type_param_bound ());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// move constructors
|
||||
ImplTraitType (ImplTraitType &&other) = default;
|
||||
ImplTraitType &operator= (ImplTraitType &&other) = default;
|
||||
|
||||
std::string as_string () const override;
|
||||
|
||||
void accept_vis (HIRFullVisitor &vis) override;
|
||||
void accept_vis (HIRTypeVisitor &vis) override;
|
||||
};
|
||||
|
||||
// An opaque value of another type that implements a set of traits
|
||||
class TraitObjectType : public Type
|
||||
{
|
||||
bool has_dyn;
|
||||
std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds;
|
||||
|
||||
protected:
|
||||
/* Use covariance to implement clone function as returning this object rather
|
||||
* than base */
|
||||
TraitObjectType *clone_type_impl () const override
|
||||
{
|
||||
return new TraitObjectType (*this);
|
||||
}
|
||||
|
||||
public:
|
||||
TraitObjectType (
|
||||
Analysis::NodeMapping mappings,
|
||||
std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
|
||||
Location locus, bool is_dyn_dispatch)
|
||||
: Type (mappings, locus), has_dyn (is_dyn_dispatch),
|
||||
type_param_bounds (std::move (type_param_bounds))
|
||||
{}
|
||||
|
||||
// copy constructor with vector clone
|
||||
TraitObjectType (TraitObjectType const &other)
|
||||
: Type (other.mappings, other.locus), has_dyn (other.has_dyn)
|
||||
{
|
||||
type_param_bounds.reserve (other.type_param_bounds.size ());
|
||||
for (const auto &e : other.type_param_bounds)
|
||||
type_param_bounds.push_back (e->clone_type_param_bound ());
|
||||
}
|
||||
|
||||
// overloaded assignment operator to clone
|
||||
TraitObjectType &operator= (TraitObjectType const &other)
|
||||
{
|
||||
mappings = other.mappings;
|
||||
has_dyn = other.has_dyn;
|
||||
locus = other.locus;
|
||||
type_param_bounds.reserve (other.type_param_bounds.size ());
|
||||
for (const auto &e : other.type_param_bounds)
|
||||
type_param_bounds.push_back (e->clone_type_param_bound ());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// move constructors
|
||||
TraitObjectType (TraitObjectType &&other) = default;
|
||||
TraitObjectType &operator= (TraitObjectType &&other) = default;
|
||||
|
||||
std::string as_string () const override;
|
||||
|
||||
void accept_vis (HIRFullVisitor &vis) override;
|
||||
void accept_vis (HIRTypeVisitor &vis) override;
|
||||
|
||||
std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds ()
|
||||
{
|
||||
return type_param_bounds;
|
||||
}
|
||||
|
||||
const std::vector<std::unique_ptr<TypeParamBound>> &
|
||||
get_type_param_bounds () const
|
||||
{
|
||||
return type_param_bounds;
|
||||
}
|
||||
};
|
||||
|
||||
// A type with parentheses around it, used to avoid ambiguity.
|
||||
class ParenthesisedType : public TypeNoBounds
|
||||
{
|
||||
std::unique_ptr<Type> type_in_parens;
|
||||
|
||||
protected:
|
||||
/* Use covariance to implement clone function as returning this object rather
|
||||
* than base */
|
||||
ParenthesisedType *clone_type_impl () const override
|
||||
{
|
||||
return new ParenthesisedType (*this);
|
||||
}
|
||||
|
||||
/* Use covariance to implement clone function as returning this object rather
|
||||
* than base */
|
||||
ParenthesisedType *clone_type_no_bounds_impl () const override
|
||||
{
|
||||
return new ParenthesisedType (*this);
|
||||
}
|
||||
|
||||
public:
|
||||
// Constructor uses Type pointer for polymorphism
|
||||
ParenthesisedType (Analysis::NodeMapping mappings,
|
||||
std::unique_ptr<Type> type_inside_parens, Location locus)
|
||||
: TypeNoBounds (mappings, locus),
|
||||
type_in_parens (std::move (type_inside_parens))
|
||||
{}
|
||||
|
||||
/* Copy constructor uses custom deep copy method for type to preserve
|
||||
* polymorphism */
|
||||
ParenthesisedType (ParenthesisedType const &other)
|
||||
: TypeNoBounds (other.mappings, other.locus),
|
||||
type_in_parens (other.type_in_parens->clone_type ())
|
||||
{}
|
||||
|
||||
// overload assignment operator to use custom clone method
|
||||
ParenthesisedType &operator= (ParenthesisedType const &other)
|
||||
{
|
||||
mappings = other.mappings;
|
||||
type_in_parens = other.type_in_parens->clone_type ();
|
||||
locus = other.locus;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// default move semantics
|
||||
ParenthesisedType (ParenthesisedType &&other) = default;
|
||||
ParenthesisedType &operator= (ParenthesisedType &&other) = default;
|
||||
|
||||
std::string as_string () const override
|
||||
{
|
||||
return "(" + type_in_parens->as_string () + ")";
|
||||
}
|
||||
|
||||
// Creates a trait bound (clone of this one's trait bound) - HACK
|
||||
TraitBound *to_trait_bound (bool in_parens ATTRIBUTE_UNUSED) const override
|
||||
{
|
||||
/* NOTE: obviously it is unknown whether the internal type is a trait bound
|
||||
* due to polymorphism, so just let the internal type handle it. As
|
||||
* parenthesised type, it must be in parentheses. */
|
||||
return type_in_parens->to_trait_bound (true);
|
||||
}
|
||||
|
||||
void accept_vis (HIRFullVisitor &vis) override;
|
||||
void accept_vis (HIRTypeVisitor &vis) override;
|
||||
};
|
||||
|
||||
// Impl trait with a single bound? Poor reference material here.
|
||||
class ImplTraitTypeOneBound : public TypeNoBounds
|
||||
{
|
||||
TraitBound trait_bound;
|
||||
|
||||
protected:
|
||||
/* Use covariance to implement clone function as returning this object rather
|
||||
* than base */
|
||||
ImplTraitTypeOneBound *clone_type_impl () const override
|
||||
{
|
||||
return new ImplTraitTypeOneBound (*this);
|
||||
}
|
||||
|
||||
/* Use covariance to implement clone function as returning this object rather
|
||||
* than base */
|
||||
ImplTraitTypeOneBound *clone_type_no_bounds_impl () const override
|
||||
{
|
||||
return new ImplTraitTypeOneBound (*this);
|
||||
}
|
||||
|
||||
public:
|
||||
ImplTraitTypeOneBound (Analysis::NodeMapping mappings, TraitBound trait_bound,
|
||||
Location locus)
|
||||
: TypeNoBounds (mappings, locus), trait_bound (std::move (trait_bound))
|
||||
{}
|
||||
|
||||
std::string as_string () const override;
|
||||
|
||||
void accept_vis (HIRFullVisitor &vis) override;
|
||||
void accept_vis (HIRTypeVisitor &vis) override;
|
||||
};
|
||||
|
||||
class TypePath; // definition moved to "rust-path.h"
|
||||
|
||||
/* A type consisting of the "product" of others (the tuple's elements) in a
|
||||
* specific order */
|
||||
class TupleType : public TypeNoBounds
|
||||
{
|
||||
std::vector<std::unique_ptr<Type>> elems;
|
||||
|
||||
public:
|
||||
// Returns whether the tuple type is the unit type, i.e. has no elements.
|
||||
bool is_unit_type () const { return elems.empty (); }
|
||||
|
||||
TupleType (Analysis::NodeMapping mappings,
|
||||
std::vector<std::unique_ptr<Type>> elems, Location locus)
|
||||
: TypeNoBounds (mappings, locus), elems (std::move (elems))
|
||||
{}
|
||||
|
||||
// copy constructor with vector clone
|
||||
TupleType (TupleType const &other)
|
||||
: TypeNoBounds (other.mappings, other.locus)
|
||||
{
|
||||
mappings = other.mappings;
|
||||
elems.reserve (other.elems.size ());
|
||||
for (const auto &e : other.elems)
|
||||
elems.push_back (e->clone_type ());
|
||||
}
|
||||
|
||||
// overloaded assignment operator to clone
|
||||
TupleType &operator= (TupleType const &other)
|
||||
{
|
||||
locus = other.locus;
|
||||
|
||||
elems.reserve (other.elems.size ());
|
||||
for (const auto &e : other.elems)
|
||||
elems.push_back (e->clone_type ());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// move constructors
|
||||
TupleType (TupleType &&other) = default;
|
||||
TupleType &operator= (TupleType &&other) = default;
|
||||
|
||||
std::string as_string () const override;
|
||||
|
||||
void accept_vis (HIRFullVisitor &vis) override;
|
||||
void accept_vis (HIRTypeVisitor &vis) override;
|
||||
|
||||
std::vector<std::unique_ptr<Type>> &get_elems () { return elems; }
|
||||
const std::vector<std::unique_ptr<Type>> &get_elems () const { return elems; }
|
||||
|
||||
protected:
|
||||
/* Use covariance to implement clone function as returning this object rather
|
||||
* than base */
|
||||
TupleType *clone_type_impl () const override { return new TupleType (*this); }
|
||||
|
||||
/* Use covariance to implement clone function as returning this object rather
|
||||
* than base */
|
||||
TupleType *clone_type_no_bounds_impl () const override
|
||||
{
|
||||
return new TupleType (*this);
|
||||
}
|
||||
};
|
||||
|
||||
/* A type with no values, representing the result of computations that never
|
||||
* complete. Expressions of NeverType can be coerced into any other types.
|
||||
* Represented as "!". */
|
||||
class NeverType : public TypeNoBounds
|
||||
{
|
||||
protected:
|
||||
/* Use covariance to implement clone function as returning this object rather
|
||||
* than base */
|
||||
NeverType *clone_type_impl () const override { return new NeverType (*this); }
|
||||
|
||||
/* Use covariance to implement clone function as returning this object rather
|
||||
* than base */
|
||||
NeverType *clone_type_no_bounds_impl () const override
|
||||
{
|
||||
return new NeverType (*this);
|
||||
}
|
||||
|
||||
public:
|
||||
NeverType (Analysis::NodeMapping mappings, Location locus)
|
||||
: TypeNoBounds (mappings, locus)
|
||||
{}
|
||||
|
||||
std::string as_string () const override { return "! (never type)"; }
|
||||
|
||||
void accept_vis (HIRFullVisitor &vis) override;
|
||||
void accept_vis (HIRTypeVisitor &vis) override;
|
||||
};
|
||||
|
||||
// A type consisting of a pointer without safety or liveness guarantees
|
||||
class RawPointerType : public TypeNoBounds
|
||||
{
|
||||
private:
|
||||
Mutability mut;
|
||||
std::unique_ptr<Type> type;
|
||||
|
||||
public:
|
||||
// Constructor requires pointer for polymorphism reasons
|
||||
RawPointerType (Analysis::NodeMapping mappings, Mutability mut,
|
||||
std::unique_ptr<Type> type, Location locus)
|
||||
: TypeNoBounds (mappings, locus), mut (mut), type (std::move (type))
|
||||
{}
|
||||
|
||||
// Copy constructor calls custom polymorphic clone function
|
||||
RawPointerType (RawPointerType const &other)
|
||||
: TypeNoBounds (other.mappings, other.locus), mut (other.mut),
|
||||
type (other.type->clone_type ())
|
||||
{}
|
||||
|
||||
// overload assignment operator to use custom clone method
|
||||
RawPointerType &operator= (RawPointerType const &other)
|
||||
{
|
||||
mappings = other.mappings;
|
||||
mut = other.mut;
|
||||
type = other.type->clone_type ();
|
||||
locus = other.locus;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// default move semantics
|
||||
RawPointerType (RawPointerType &&other) = default;
|
||||
RawPointerType &operator= (RawPointerType &&other) = default;
|
||||
|
||||
std::string as_string () const override;
|
||||
|
||||
void accept_vis (HIRFullVisitor &vis) override;
|
||||
void accept_vis (HIRTypeVisitor &vis) override;
|
||||
|
||||
std::unique_ptr<Type> &get_type () { return type; }
|
||||
|
||||
Mutability get_mut () const { return mut; }
|
||||
|
||||
bool is_mut () const { return mut == Mutability::Mut; }
|
||||
|
||||
bool is_const () const { return mut == Mutability::Imm; }
|
||||
|
||||
std::unique_ptr<Type> &get_base_type () { return type; }
|
||||
|
||||
protected:
|
||||
/* Use covariance to implement clone function as returning this object rather
|
||||
* than base */
|
||||
RawPointerType *clone_type_impl () const override
|
||||
{
|
||||
return new RawPointerType (*this);
|
||||
}
|
||||
|
||||
/* Use covariance to implement clone function as returning this object rather
|
||||
* than base */
|
||||
RawPointerType *clone_type_no_bounds_impl () const override
|
||||
{
|
||||
return new RawPointerType (*this);
|
||||
}
|
||||
};
|
||||
|
||||
// A type pointing to memory owned by another value
|
||||
class ReferenceType : public TypeNoBounds
|
||||
{
|
||||
// bool has_lifetime; // TODO: handle in lifetime or something?
|
||||
Lifetime lifetime;
|
||||
|
||||
Mutability mut;
|
||||
std::unique_ptr<Type> type;
|
||||
|
||||
public:
|
||||
// Returns whether the reference is mutable or immutable.
|
||||
bool is_mut () const { return mut == Mutability::Mut; }
|
||||
|
||||
// Returns whether the reference has a lifetime.
|
||||
bool has_lifetime () const { return !lifetime.is_error (); }
|
||||
|
||||
// Constructor
|
||||
ReferenceType (Analysis::NodeMapping mappings, Mutability mut,
|
||||
std::unique_ptr<Type> type_no_bounds, Location locus,
|
||||
Lifetime lifetime)
|
||||
: TypeNoBounds (mappings, locus), lifetime (std::move (lifetime)),
|
||||
mut (mut), type (std::move (type_no_bounds))
|
||||
{}
|
||||
|
||||
// Copy constructor with custom clone method
|
||||
ReferenceType (ReferenceType const &other)
|
||||
: TypeNoBounds (other.mappings, other.locus), lifetime (other.lifetime),
|
||||
mut (other.mut), type (other.type->clone_type ())
|
||||
{}
|
||||
|
||||
// Operator overload assignment operator to custom clone the unique pointer
|
||||
ReferenceType &operator= (ReferenceType const &other)
|
||||
{
|
||||
mappings = other.mappings;
|
||||
lifetime = other.lifetime;
|
||||
mut = other.mut;
|
||||
type = other.type->clone_type ();
|
||||
locus = other.locus;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// move constructors
|
||||
ReferenceType (ReferenceType &&other) = default;
|
||||
ReferenceType &operator= (ReferenceType &&other) = default;
|
||||
|
||||
std::string as_string () const override;
|
||||
|
||||
void accept_vis (HIRFullVisitor &vis) override;
|
||||
void accept_vis (HIRTypeVisitor &vis) override;
|
||||
|
||||
Lifetime &get_lifetime () { return lifetime; }
|
||||
|
||||
Mutability get_mut () const { return mut; }
|
||||
|
||||
std::unique_ptr<Type> &get_base_type () { return type; }
|
||||
|
||||
protected:
|
||||
/* Use covariance to implement clone function as returning this object rather
|
||||
* than base */
|
||||
ReferenceType *clone_type_impl () const override
|
||||
{
|
||||
return new ReferenceType (*this);
|
||||
}
|
||||
|
||||
/* Use covariance to implement clone function as returning this object rather
|
||||
* than base */
|
||||
ReferenceType *clone_type_no_bounds_impl () const override
|
||||
{
|
||||
return new ReferenceType (*this);
|
||||
}
|
||||
};
|
||||
|
||||
// A fixed-size sequence of elements of a specified type
|
||||
class ArrayType : public TypeNoBounds
|
||||
{
|
||||
std::unique_ptr<Type> elem_type;
|
||||
std::unique_ptr<Expr> size;
|
||||
|
||||
public:
|
||||
// Constructor requires pointers for polymorphism
|
||||
ArrayType (Analysis::NodeMapping mappings, std::unique_ptr<Type> type,
|
||||
std::unique_ptr<Expr> array_size, Location locus)
|
||||
: TypeNoBounds (mappings, locus), elem_type (std::move (type)),
|
||||
size (std::move (array_size))
|
||||
{}
|
||||
|
||||
// Copy constructor requires deep copies of both unique pointers
|
||||
ArrayType (ArrayType const &other)
|
||||
: TypeNoBounds (other.mappings, other.locus),
|
||||
elem_type (other.elem_type->clone_type ()),
|
||||
size (other.size->clone_expr ())
|
||||
{}
|
||||
|
||||
// Overload assignment operator to deep copy pointers
|
||||
ArrayType &operator= (ArrayType const &other)
|
||||
{
|
||||
mappings = other.mappings;
|
||||
elem_type = other.elem_type->clone_type ();
|
||||
size = other.size->clone_expr ();
|
||||
locus = other.locus;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// move constructors
|
||||
ArrayType (ArrayType &&other) = default;
|
||||
ArrayType &operator= (ArrayType &&other) = default;
|
||||
|
||||
std::string as_string () const override;
|
||||
|
||||
void accept_vis (HIRFullVisitor &vis) override;
|
||||
void accept_vis (HIRTypeVisitor &vis) override;
|
||||
|
||||
Type *get_element_type () { return elem_type.get (); }
|
||||
|
||||
Expr *get_size_expr () { return size.get (); }
|
||||
|
||||
protected:
|
||||
/* Use covariance to implement clone function as returning this object rather
|
||||
* than base */
|
||||
ArrayType *clone_type_impl () const override { return new ArrayType (*this); }
|
||||
|
||||
/* Use covariance to implement clone function as returning this object rather
|
||||
* than base */
|
||||
ArrayType *clone_type_no_bounds_impl () const override
|
||||
{
|
||||
return new ArrayType (*this);
|
||||
}
|
||||
};
|
||||
|
||||
/* A dynamically-sized type representing a "view" into a sequence of elements of
|
||||
* a type */
|
||||
class SliceType : public TypeNoBounds
|
||||
{
|
||||
std::unique_ptr<Type> elem_type;
|
||||
|
||||
public:
|
||||
// Constructor requires pointer for polymorphism
|
||||
SliceType (Analysis::NodeMapping mappings, std::unique_ptr<Type> type,
|
||||
Location locus)
|
||||
: TypeNoBounds (mappings, locus), elem_type (std::move (type))
|
||||
{}
|
||||
|
||||
// Copy constructor requires deep copy of Type smart pointer
|
||||
SliceType (SliceType const &other)
|
||||
: TypeNoBounds (other.mappings, other.locus),
|
||||
elem_type (other.elem_type->clone_type ())
|
||||
{}
|
||||
|
||||
// Overload assignment operator to deep copy
|
||||
SliceType &operator= (SliceType const &other)
|
||||
{
|
||||
mappings = other.mappings;
|
||||
elem_type = other.elem_type->clone_type ();
|
||||
locus = other.locus;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// move constructors
|
||||
SliceType (SliceType &&other) = default;
|
||||
SliceType &operator= (SliceType &&other) = default;
|
||||
|
||||
std::string as_string () const override;
|
||||
|
||||
void accept_vis (HIRFullVisitor &vis) override;
|
||||
void accept_vis (HIRTypeVisitor &vis) override;
|
||||
|
||||
std::unique_ptr<Type> &get_element_type () { return elem_type; }
|
||||
|
||||
protected:
|
||||
/* Use covariance to implement clone function as returning this object rather
|
||||
* than base */
|
||||
SliceType *clone_type_impl () const override { return new SliceType (*this); }
|
||||
|
||||
/* Use covariance to implement clone function as returning this object rather
|
||||
* than base */
|
||||
SliceType *clone_type_no_bounds_impl () const override
|
||||
{
|
||||
return new SliceType (*this);
|
||||
}
|
||||
};
|
||||
|
||||
/* Type used in generic arguments to explicitly request type inference (wildcard
|
||||
* pattern) */
|
||||
class InferredType : public TypeNoBounds
|
||||
{
|
||||
// e.g. Vec<_> = whatever
|
||||
protected:
|
||||
/* Use covariance to implement clone function as returning this object rather
|
||||
* than base */
|
||||
InferredType *clone_type_impl () const override
|
||||
{
|
||||
return new InferredType (*this);
|
||||
}
|
||||
|
||||
/* Use covariance to implement clone function as returning this object rather
|
||||
* than base */
|
||||
InferredType *clone_type_no_bounds_impl () const override
|
||||
{
|
||||
return new InferredType (*this);
|
||||
}
|
||||
|
||||
public:
|
||||
InferredType (Analysis::NodeMapping mappings, Location locus)
|
||||
: TypeNoBounds (mappings, locus)
|
||||
{}
|
||||
|
||||
std::string as_string () const override;
|
||||
|
||||
void accept_vis (HIRFullVisitor &vis) override;
|
||||
void accept_vis (HIRTypeVisitor &vis) override;
|
||||
};
|
||||
|
||||
class QualifiedPathInType; // definition moved to "rust-path.h"
|
||||
|
||||
// A possibly named param used in a BaseFunctionType
|
||||
struct MaybeNamedParam
|
||||
{
|
||||
public:
|
||||
enum ParamKind
|
||||
{
|
||||
UNNAMED,
|
||||
IDENTIFIER,
|
||||
WILDCARD
|
||||
};
|
||||
|
||||
private:
|
||||
std::unique_ptr<Type> param_type;
|
||||
|
||||
ParamKind param_kind;
|
||||
Identifier name; // technically, can be an identifier or '_'
|
||||
|
||||
Location locus;
|
||||
|
||||
public:
|
||||
MaybeNamedParam (Identifier name, ParamKind param_kind,
|
||||
std::unique_ptr<Type> param_type, Location locus)
|
||||
: param_type (std::move (param_type)), param_kind (param_kind),
|
||||
name (std::move (name)), locus (locus)
|
||||
{}
|
||||
|
||||
// Copy constructor with clone
|
||||
MaybeNamedParam (MaybeNamedParam const &other)
|
||||
: param_type (other.param_type->clone_type ()),
|
||||
param_kind (other.param_kind), name (other.name), locus (other.locus)
|
||||
{}
|
||||
|
||||
~MaybeNamedParam () = default;
|
||||
|
||||
// Overloaded assignment operator with clone
|
||||
MaybeNamedParam &operator= (MaybeNamedParam const &other)
|
||||
{
|
||||
name = other.name;
|
||||
param_kind = other.param_kind;
|
||||
param_type = other.param_type->clone_type ();
|
||||
locus = other.locus;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// move constructors
|
||||
MaybeNamedParam (MaybeNamedParam &&other) = default;
|
||||
MaybeNamedParam &operator= (MaybeNamedParam &&other) = default;
|
||||
|
||||
std::string as_string () const;
|
||||
|
||||
// Returns whether the param is in an error state.
|
||||
bool is_error () const { return param_type == nullptr; }
|
||||
|
||||
// Creates an error state param.
|
||||
static MaybeNamedParam create_error ()
|
||||
{
|
||||
return MaybeNamedParam ("", UNNAMED, nullptr, Location ());
|
||||
}
|
||||
|
||||
Location get_locus () const { return locus; }
|
||||
|
||||
std::unique_ptr<Type> &get_type ()
|
||||
{
|
||||
rust_assert (param_type != nullptr);
|
||||
return param_type;
|
||||
}
|
||||
|
||||
ParamKind get_param_kind () const { return param_kind; }
|
||||
|
||||
Identifier get_name () const { return name; }
|
||||
};
|
||||
|
||||
/* A function pointer type - can be created via coercion from function items and
|
||||
* non- capturing closures. */
|
||||
class BareFunctionType : public TypeNoBounds
|
||||
{
|
||||
// bool has_for_lifetimes;
|
||||
// ForLifetimes for_lifetimes;
|
||||
std::vector<LifetimeParam> for_lifetimes; // inlined version
|
||||
|
||||
FunctionQualifiers function_qualifiers;
|
||||
std::vector<MaybeNamedParam> params;
|
||||
bool is_variadic;
|
||||
|
||||
std::unique_ptr<Type> return_type; // inlined version
|
||||
|
||||
public:
|
||||
// Whether a return type is defined with the function.
|
||||
bool has_return_type () const { return return_type != nullptr; }
|
||||
|
||||
// Whether the function has ForLifetimes.
|
||||
bool has_for_lifetimes () const { return !for_lifetimes.empty (); }
|
||||
|
||||
BareFunctionType (Analysis::NodeMapping mappings,
|
||||
std::vector<LifetimeParam> lifetime_params,
|
||||
FunctionQualifiers qualifiers,
|
||||
std::vector<MaybeNamedParam> named_params, bool is_variadic,
|
||||
std::unique_ptr<Type> type, Location locus)
|
||||
: TypeNoBounds (mappings, locus),
|
||||
for_lifetimes (std::move (lifetime_params)),
|
||||
function_qualifiers (std::move (qualifiers)),
|
||||
params (std::move (named_params)), is_variadic (is_variadic),
|
||||
return_type (std::move (type))
|
||||
{}
|
||||
|
||||
// Copy constructor with clone
|
||||
BareFunctionType (BareFunctionType const &other)
|
||||
: TypeNoBounds (other.mappings, other.locus),
|
||||
for_lifetimes (other.for_lifetimes),
|
||||
function_qualifiers (other.function_qualifiers), params (other.params),
|
||||
is_variadic (other.is_variadic),
|
||||
return_type (other.return_type->clone_type ())
|
||||
{}
|
||||
|
||||
// Overload assignment operator to deep copy
|
||||
BareFunctionType &operator= (BareFunctionType const &other)
|
||||
{
|
||||
mappings = other.mappings;
|
||||
for_lifetimes = other.for_lifetimes;
|
||||
function_qualifiers = other.function_qualifiers;
|
||||
params = other.params;
|
||||
is_variadic = other.is_variadic;
|
||||
return_type = other.return_type->clone_type ();
|
||||
locus = other.locus;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// move constructors
|
||||
BareFunctionType (BareFunctionType &&other) = default;
|
||||
BareFunctionType &operator= (BareFunctionType &&other) = default;
|
||||
|
||||
std::string as_string () const override;
|
||||
|
||||
void accept_vis (HIRFullVisitor &vis) override;
|
||||
void accept_vis (HIRTypeVisitor &vis) override;
|
||||
|
||||
std::vector<MaybeNamedParam> &get_function_params () { return params; }
|
||||
const std::vector<MaybeNamedParam> &get_function_params () const
|
||||
{
|
||||
return params;
|
||||
}
|
||||
|
||||
// TODO: would a "vis_type" be better?
|
||||
std::unique_ptr<Type> &get_return_type ()
|
||||
{
|
||||
rust_assert (has_return_type ());
|
||||
return return_type;
|
||||
}
|
||||
|
||||
protected:
|
||||
/* Use covariance to implement clone function as returning this object rather
|
||||
* than base */
|
||||
BareFunctionType *clone_type_impl () const override
|
||||
{
|
||||
return new BareFunctionType (*this);
|
||||
}
|
||||
|
||||
/* Use covariance to implement clone function as returning this object rather
|
||||
* than base */
|
||||
BareFunctionType *clone_type_no_bounds_impl () const override
|
||||
{
|
||||
return new BareFunctionType (*this);
|
||||
}
|
||||
};
|
||||
|
||||
/* TODO: possible types
|
||||
* struct type?
|
||||
* "enum" (tagged union) type?
|
||||
* C-like union type?
|
||||
* function item type?
|
||||
* closure expression types?
|
||||
* primitive types (bool, int, float, char, str (the slice))
|
||||
* Although supposedly TypePaths are used to reference these types (including
|
||||
* primitives) */
|
||||
|
||||
/* FIXME: Incomplete spec references:
|
||||
* anonymous type parameters, aka "impl Trait in argument position" - impl then
|
||||
* trait bounds abstract return types, aka "impl Trait in return position" -
|
||||
* impl then trait bounds */
|
||||
} // namespace HIR
|
||||
} // namespace Rust
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user