// Copyright (C) 2020-2023 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
// .
#ifndef RUST_AST_LOWER_TYPE
#define RUST_AST_LOWER_TYPE
#include "rust-ast-lower-base.h"
#include "rust-diagnostics.h"
#include "rust-ast-lower-expr.h"
namespace Rust {
namespace HIR {
class ASTLowerTypePath : public ASTLoweringBase
{
protected:
using Rust::HIR::ASTLoweringBase::visit;
public:
static HIR::TypePath *translate (AST::TypePath &type);
void visit (AST::TypePathSegmentFunction &segment) override;
void visit (AST::TypePathSegment &segment) override;
void visit (AST::TypePathSegmentGeneric &segment) override;
void visit (AST::TypePath &path) override;
protected:
HIR::TypePathSegment *translated_segment;
private:
HIR::TypePath *translated;
};
class ASTLowerQualifiedPathInType : public ASTLowerTypePath
{
using ASTLowerTypePath::visit;
public:
static HIR::QualifiedPathInType *translate (AST::QualifiedPathInType &type);
void visit (AST::QualifiedPathInType &path) override;
private:
HIR::QualifiedPathInType *translated;
};
class ASTLoweringType : public ASTLoweringBase
{
using Rust::HIR::ASTLoweringBase::visit;
public:
static HIR::Type *translate (AST::Type *type)
{
ASTLoweringType resolver;
type->accept_vis (resolver);
rust_assert (resolver.translated != nullptr);
resolver.mappings->insert_hir_type (resolver.translated);
resolver.mappings->insert_location (
resolver.translated->get_mappings ().get_hirid (),
resolver.translated->get_locus ());
return resolver.translated;
}
void visit (AST::BareFunctionType &fntype) override
{
bool is_variadic = false;
std::vector lifetime_params;
HIR::FunctionQualifiers qualifiers
= lower_qualifiers (fntype.get_function_qualifiers ());
std::vector named_params;
for (auto ¶m : fntype.get_function_params ())
{
HIR::MaybeNamedParam::ParamKind kind;
switch (param.get_param_kind ())
{
case AST::MaybeNamedParam::ParamKind::UNNAMED:
kind = HIR::MaybeNamedParam::ParamKind::UNNAMED;
break;
case AST::MaybeNamedParam::ParamKind::IDENTIFIER:
kind = HIR::MaybeNamedParam::ParamKind::IDENTIFIER;
break;
case AST::MaybeNamedParam::ParamKind::WILDCARD:
kind = HIR::MaybeNamedParam::ParamKind::WILDCARD;
break;
default:
gcc_unreachable ();
}
HIR::Type *param_type
= ASTLoweringType::translate (param.get_type ().get ());
HIR::MaybeNamedParam p (param.get_name (), kind,
std::unique_ptr (param_type),
param.get_locus ());
named_params.push_back (std::move (p));
}
HIR::Type *return_type = nullptr;
if (fntype.has_return_type ())
{
return_type
= ASTLoweringType::translate (fntype.get_return_type ().get ());
}
auto crate_num = mappings->get_current_crate ();
Analysis::NodeMapping mapping (crate_num, fntype.get_node_id (),
mappings->get_next_hir_id (crate_num),
mappings->get_next_localdef_id (crate_num));
translated = new HIR::BareFunctionType (
std::move (mapping), std::move (lifetime_params), std::move (qualifiers),
std::move (named_params), is_variadic,
std::unique_ptr (return_type), fntype.get_locus ());
}
void visit (AST::TupleType &tuple) override
{
std::vector> elems;
for (auto &e : tuple.get_elems ())
{
HIR::Type *t = ASTLoweringType::translate (e.get ());
elems.push_back (std::unique_ptr (t));
}
auto crate_num = mappings->get_current_crate ();
Analysis::NodeMapping mapping (crate_num, tuple.get_node_id (),
mappings->get_next_hir_id (crate_num),
mappings->get_next_localdef_id (crate_num));
translated = new HIR::TupleType (std::move (mapping), std::move (elems),
tuple.get_locus ());
}
void visit (AST::TypePath &path) override
{
translated = ASTLowerTypePath::translate (path);
}
void visit (AST::QualifiedPathInType &path) override
{
translated = ASTLowerQualifiedPathInType::translate (path);
}
void visit (AST::ArrayType &type) override
{
HIR::Type *translated_type
= ASTLoweringType::translate (type.get_elem_type ().get ());
HIR::Expr *array_size
= ASTLoweringExpr::translate (type.get_size_expr ().get ());
auto crate_num = mappings->get_current_crate ();
Analysis::NodeMapping mapping (crate_num, type.get_node_id (),
mappings->get_next_hir_id (crate_num),
mappings->get_next_localdef_id (crate_num));
translated
= new HIR::ArrayType (mapping,
std::unique_ptr (translated_type),
std::unique_ptr (array_size),
type.get_locus ());
}
void visit (AST::ReferenceType &type) override
{
HIR::Lifetime lifetime = lower_lifetime (type.get_lifetime ());
HIR::Type *base_type
= ASTLoweringType::translate (type.get_base_type ().get ());
auto crate_num = mappings->get_current_crate ();
Analysis::NodeMapping mapping (crate_num, type.get_node_id (),
mappings->get_next_hir_id (crate_num),
mappings->get_next_localdef_id (crate_num));
translated = new HIR::ReferenceType (mapping,
type.get_has_mut () ? Mutability::Mut
: Mutability::Imm,
std::unique_ptr (base_type),
type.get_locus (), lifetime);
}
void visit (AST::RawPointerType &type) override
{
HIR::Type *base_type
= ASTLoweringType::translate (type.get_type_pointed_to ().get ());
auto crate_num = mappings->get_current_crate ();
Analysis::NodeMapping mapping (crate_num, type.get_node_id (),
mappings->get_next_hir_id (crate_num),
mappings->get_next_localdef_id (crate_num));
translated
= new HIR::RawPointerType (mapping,
type.get_pointer_type ()
== AST::RawPointerType::PointerType::MUT
? Mutability::Mut
: Mutability::Imm,
std::unique_ptr (base_type),
type.get_locus ());
}
void visit (AST::SliceType &type) override
{
HIR::Type *base_type
= ASTLoweringType::translate (type.get_elem_type ().get ());
auto crate_num = mappings->get_current_crate ();
Analysis::NodeMapping mapping (crate_num, type.get_node_id (),
mappings->get_next_hir_id (crate_num),
mappings->get_next_localdef_id (crate_num));
translated
= new HIR::SliceType (mapping, std::unique_ptr (base_type),
type.get_locus ());
}
void visit (AST::InferredType &type) override
{
auto crate_num = mappings->get_current_crate ();
Analysis::NodeMapping mapping (crate_num, type.get_node_id (),
mappings->get_next_hir_id (crate_num),
mappings->get_next_localdef_id (crate_num));
translated = new HIR::InferredType (mapping, type.get_locus ());
}
void visit (AST::NeverType &type) override
{
auto crate_num = mappings->get_current_crate ();
Analysis::NodeMapping mapping (crate_num, type.get_node_id (),
mappings->get_next_hir_id (crate_num),
mappings->get_next_localdef_id (crate_num));
translated = new HIR::NeverType (mapping, type.get_locus ());
}
void visit (AST::TraitObjectTypeOneBound &type) override;
void visit (AST::TraitObjectType &type) override;
private:
ASTLoweringType () : ASTLoweringBase (), translated (nullptr) {}
HIR::Type *translated;
};
class ASTLowerGenericParam : public ASTLoweringBase
{
using Rust::HIR::ASTLoweringBase::visit;
public:
static HIR::GenericParam *translate (AST::GenericParam *param)
{
ASTLowerGenericParam resolver;
param->accept_vis (resolver);
rust_assert (resolver.translated != nullptr);
resolver.mappings->insert_location (
resolver.translated->get_mappings ().get_hirid (), param->get_locus ());
resolver.mappings->insert_hir_generic_param (resolver.translated);
return resolver.translated;
}
void visit (AST::LifetimeParam ¶m) override
{
auto crate_num = mappings->get_current_crate ();
Analysis::NodeMapping mapping (crate_num, param.get_node_id (),
mappings->get_next_hir_id (crate_num),
mappings->get_next_localdef_id (crate_num));
HIR::Lifetime lt (mapping, param.get_lifetime ().get_lifetime_type (),
param.get_lifetime ().get_lifetime_name (),
param.get_lifetime ().get_locus ());
translated = new HIR::LifetimeParam (mapping, lt, param.get_locus (),
std::vector ());
}
void visit (AST::ConstGenericParam ¶m) override
{
auto crate_num = mappings->get_current_crate ();
Analysis::NodeMapping mapping (crate_num, param.get_node_id (),
mappings->get_next_hir_id (crate_num),
mappings->get_next_localdef_id (crate_num));
auto type = ASTLoweringType::translate (param.get_type ().get ());
HIR::Expr *default_expr = nullptr;
if (param.has_default_value ())
default_expr = ASTLoweringExpr::translate (
param.get_default_value ().get_expression ().get ());
translated
= new HIR::ConstGenericParam (param.get_name (),
std::unique_ptr (type),
std::unique_ptr (default_expr),
mapping, param.get_locus ());
}
void visit (AST::TypeParam ¶m) override
{
AST::Attribute outer_attr = AST::Attribute::create_empty ();
std::vector> type_param_bounds;
if (param.has_type_param_bounds ())
{
for (auto &bound : param.get_type_param_bounds ())
{
HIR::TypeParamBound *lowered_bound = lower_bound (bound.get ());
type_param_bounds.push_back (
std::unique_ptr (lowered_bound));
}
}
HIR::Type *type = param.has_type ()
? ASTLoweringType::translate (param.get_type ().get ())
: nullptr;
auto crate_num = mappings->get_current_crate ();
Analysis::NodeMapping mapping (crate_num, param.get_node_id (),
mappings->get_next_hir_id (crate_num),
mappings->get_next_localdef_id (crate_num));
translated
= new HIR::TypeParam (mapping, param.get_type_representation (),
param.get_locus (), std::move (type_param_bounds),
std::unique_ptr (type),
std::move (outer_attr));
}
private:
ASTLowerGenericParam () : ASTLoweringBase (), translated (nullptr) {}
HIR::GenericParam *translated;
};
class ASTLoweringTypeBounds : public ASTLoweringBase
{
using Rust::HIR::ASTLoweringBase::visit;
public:
static HIR::TypeParamBound *translate (AST::TypeParamBound *type)
{
ASTLoweringTypeBounds resolver;
type->accept_vis (resolver);
rust_assert (resolver.translated != nullptr);
resolver.mappings->insert_location (
resolver.translated->get_mappings ().get_hirid (),
resolver.translated->get_locus ());
return resolver.translated;
}
void visit (AST::TraitBound &bound) override
{
// FIXME
std::vector lifetimes;
AST::TypePath &ast_trait_path = bound.get_type_path ();
HIR::TypePath *trait_path = ASTLowerTypePath::translate (ast_trait_path);
auto crate_num = mappings->get_current_crate ();
Analysis::NodeMapping mapping (crate_num, bound.get_node_id (),
mappings->get_next_hir_id (crate_num),
UNKNOWN_LOCAL_DEFID);
translated = new HIR::TraitBound (mapping, *trait_path, bound.get_locus (),
bound.is_in_parens (),
bound.has_opening_question_mark ());
}
void visit (AST::Lifetime &bound) override
{
HIR::Lifetime lifetime = lower_lifetime (bound);
translated = new HIR::Lifetime (lifetime);
}
private:
ASTLoweringTypeBounds () : ASTLoweringBase (), translated (nullptr) {}
HIR::TypeParamBound *translated;
};
class ASTLowerWhereClauseItem : public ASTLoweringBase
{
using Rust::HIR::ASTLoweringBase::visit;
public:
static HIR::WhereClauseItem *translate (AST::WhereClauseItem &item)
{
ASTLowerWhereClauseItem compiler;
item.accept_vis (compiler);
rust_assert (compiler.translated != nullptr);
// FIXME
// compiler.mappings->insert_location (
// compiler.translated->get_mappings ().get_hirid (),
// compiler.translated->get_locus ());
return compiler.translated;
}
void visit (AST::LifetimeWhereClauseItem &item) override
{
HIR::Lifetime l = lower_lifetime (item.get_lifetime ());
std::vector lifetime_bounds;
for (auto &lifetime_bound : item.get_lifetime_bounds ())
{
HIR::Lifetime ll = lower_lifetime (lifetime_bound);
lifetime_bounds.push_back (std::move (ll));
}
auto crate_num = mappings->get_current_crate ();
Analysis::NodeMapping mapping (crate_num, item.get_node_id (),
mappings->get_next_hir_id (crate_num),
UNKNOWN_LOCAL_DEFID);
translated = new HIR::LifetimeWhereClauseItem (mapping, std::move (l),
std::move (lifetime_bounds),
item.get_locus ());
}
void visit (AST::TypeBoundWhereClauseItem &item) override
{
// FIXME
std::vector for_lifetimes;
std::unique_ptr bound_type = std::unique_ptr (
ASTLoweringType::translate (item.get_type ().get ()));
std::vector> type_param_bounds;
for (auto &bound : item.get_type_param_bounds ())
{
HIR::TypeParamBound *b
= ASTLoweringTypeBounds::translate (bound.get ());
type_param_bounds.push_back (std::unique_ptr (b));
}
auto crate_num = mappings->get_current_crate ();
Analysis::NodeMapping mapping (crate_num, item.get_node_id (),
mappings->get_next_hir_id (crate_num),
UNKNOWN_LOCAL_DEFID);
translated
= new HIR::TypeBoundWhereClauseItem (mapping, std::move (for_lifetimes),
std::move (bound_type),
std::move (type_param_bounds),
item.get_locus ());
}
private:
ASTLowerWhereClauseItem () : ASTLoweringBase (), translated (nullptr) {}
HIR::WhereClauseItem *translated;
};
} // namespace HIR
} // namespace Rust
#endif // RUST_AST_LOWER_TYPE