return error_mark_node;
}
- auto capacity_tyty = array_tyty.get_capacity ();
- tree capacity_expr = capacity_tyty->get_value ();
- if (!TREE_CONSTANT (capacity_expr))
+ auto capacity_ty = array_tyty.get_capacity ();
+
+ // Check if capacity is a const type
+ if (capacity_ty->get_kind () != TyTy::TypeKind::CONST)
+ {
+ rust_error_at (array_tyty.get_locus (),
+ "array capacity is not a const type");
+ return error_mark_node;
+ }
+
+ auto *capacity_const = capacity_ty->as_const_type ();
+
+ rust_assert (capacity_const->const_kind ()
+ == TyTy::BaseConstType::ConstKind::Value);
+ auto &capacity_value = *static_cast<TyTy::ConstValueType *> (capacity_const);
+ auto cap_tree = capacity_value.get_value ();
+ if (error_operand_p (cap_tree) || !TREE_CONSTANT (cap_tree))
{
- rust_error_at (expr_locus, "non const num copies %qT", capacity_expr);
+ rust_error_at (expr_locus, "non const num copies %qT", cap_tree);
return error_mark_node;
}
ctx->push_block (init_block);
tree tmp;
- tree stmts = Backend::array_initializer (fndecl, init_block, array_type,
- capacity_expr, translated_expr,
- &tmp, expr_locus);
+ tree stmts
+ = Backend::array_initializer (fndecl, init_block, array_type, cap_tree,
+ translated_expr, &tmp, expr_locus);
ctx->add_statement (stmts);
tree block = ctx->pop_block ();
#include "rust-hir-pattern.h"
#include "rust-system.h"
#include "rust-tyty.h"
+#include "tree.h"
namespace Rust {
namespace Compile {
// for array type scrutinee, we can simply get the capacity as a
// const and calculate how many elements to skip
auto array_ty = static_cast<TyTy::ArrayType *> (lookup);
- auto cap_tree = array_ty->get_capacity ()->get_value ();
+ auto capacity_ty = array_ty->get_capacity ();
+
+ rust_assert (capacity_ty->get_kind () == TyTy::TypeKind::CONST);
+ auto *capacity_const = capacity_ty->as_const_type ();
+ rust_assert (capacity_const->const_kind ()
+ == TyTy::BaseConstType::ConstKind::Value);
+ auto &capacity_value
+ = *static_cast<TyTy::ConstValueType *> (capacity_const);
+ auto cap_tree = capacity_value.get_value ();
+
+ rust_assert (!error_operand_p (cap_tree));
+
size_t cap_wi = (size_t) wi::to_wide (cap_tree).to_uhwi ();
element_index = cap_wi - items.get_upper_patterns ().size ();
for (auto &pattern_member : items.get_upper_patterns ())
case TyTy::TypeKind::ARRAY:
{
auto array_ty = static_cast<TyTy::ArrayType *> (lookup);
- auto cap_tree = array_ty->get_capacity ()->get_value ();
+ auto capacity_ty = array_ty->get_capacity ();
+
+ rust_assert (capacity_ty->get_kind () == TyTy::TypeKind::CONST);
+ auto *capacity_const = capacity_ty->as_const_type ();
+ rust_assert (capacity_const->const_kind ()
+ == TyTy::BaseConstType::ConstKind::Value);
+ auto &capacity_value
+ = *static_cast<TyTy::ConstValueType *> (capacity_const);
+ auto cap_tree = capacity_value.get_value ();
+
+ rust_assert (!error_operand_p (cap_tree));
+
size_t cap_wi = (size_t) wi::to_wide (cap_tree).to_uhwi ();
element_index = cap_wi - items.get_upper_patterns ().size ();
for (auto &pattern_member : items.get_upper_patterns ())
}
void
-TyTyResolveCompile::visit (const TyTy::ParamType &)
+TyTyResolveCompile::visit (const TyTy::ParamType &type)
{
translated = error_mark_node;
}
void
-TyTyResolveCompile::visit (const TyTy::ConstType &)
+TyTyResolveCompile::visit (const TyTy::ConstParamType &type)
+{
+ translated = error_mark_node;
+}
+
+void
+TyTyResolveCompile::visit (const TyTy::ConstValueType &type)
+{
+ translated = error_mark_node;
+}
+
+void
+TyTyResolveCompile::visit (const TyTy::ConstInferType &type)
+{
+ translated = error_mark_node;
+}
+
+void
+TyTyResolveCompile::visit (const TyTy::ConstErrorType &type)
{
translated = error_mark_node;
}
{
tree element_type
= TyTyResolveCompile::compile (ctx, type.get_element_type ());
- TyTy::ConstType *const_capacity = type.get_capacity ();
- tree folded_capacity_expr = const_capacity->get_value ();
+ auto const_capacity = type.get_capacity ();
+
+ // Check if capacity is a const type
+ if (const_capacity->get_kind () != TyTy::TypeKind::CONST)
+ {
+ rust_error_at (type.get_locus (), "array capacity is not a const type");
+ translated = error_mark_node;
+ return;
+ }
+
+ auto *capacity_const = const_capacity->as_const_type ();
+
+ rust_assert (capacity_const->const_kind ()
+ == TyTy::BaseConstType::ConstKind::Value);
+ auto &capacity_value = *static_cast<TyTy::ConstValueType *> (capacity_const);
+ auto folded_capacity_expr = capacity_value.get_value ();
// build_index_type takes the maximum index, which is one less than
// the length.
void visit (const TyTy::ReferenceType &) override;
void visit (const TyTy::PointerType &) override;
void visit (const TyTy::ParamType &) override;
- void visit (const TyTy::ConstType &) override;
+ void visit (const TyTy::ConstParamType &) override;
+ void visit (const TyTy::ConstValueType &) override;
+ void visit (const TyTy::ConstInferType &) override;
+ void visit (const TyTy::ConstErrorType &) override;
void visit (const TyTy::StrType &) override;
void visit (const TyTy::NeverType &) override;
void visit (const TyTy::PlaceholderType &) override;
tree capacity = Compile::HIRCompileBase::query_compile_const_expr (
ctx, expected_ty, *literal_capacity);
- TyTy::ConstType *capacity_expr
- = new TyTy::ConstType (TyTy::ConstType::ConstKind::Value, "",
- expected_ty, capacity, {},
- literal_capacity->get_locus (),
- literal_capacity->get_mappings ().get_hirid (),
- literal_capacity->get_mappings ().get_hirid (),
- {});
-
- TyTy::ArrayType *array
- = new TyTy::ArrayType (array_mapping.get_hirid (), locus,
- capacity_expr, TyTy::TyVar (u8->get_ref ()));
+ HirId capacity_expr_id = literal_capacity->get_mappings ().get_hirid ();
+ auto capacity_expr
+ = new TyTy::ConstValueType (capacity, expected_ty, capacity_expr_id,
+ capacity_expr_id);
+ context->insert_type (literal_capacity->get_mappings (),
+ capacity_expr->as_base_type ());
+
+ TyTy::ArrayType *array = new TyTy::ArrayType (
+ array_mapping.get_hirid (), locus,
+ TyTy::TyVar (capacity_expr->as_base_type ()->get_ty_ref ()),
+ TyTy::TyVar (u8->get_ref ()));
context->insert_type (array_mapping, array);
infered = new TyTy::ReferenceType (expr_mappings.get_hirid (),
= Compile::HIRCompileBase::query_compile_const_expr (
ctx, specified_type, expr);
- TyTy::ConstType *default_const_decl
- = new TyTy::ConstType (TyTy::ConstType::ConstKind::Value,
- param.get_name (), specified_type,
- default_value, {}, param.get_locus (),
- expr.get_mappings ().get_hirid (),
- expr.get_mappings ().get_hirid (), {});
+ auto default_const_decl
+ = new TyTy::ConstValueType (default_value, specified_type,
+ expr.get_mappings ().get_hirid (),
+ expr.get_mappings ().get_hirid (),
+ {});
context->insert_type (expr.get_mappings (), default_const_decl);
}
- TyTy::ConstType *const_decl
- = new TyTy::ConstType (TyTy::ConstType::ConstKind::Decl,
- param.get_name (), specified_type,
- error_mark_node, {}, param.get_locus (),
- param.get_mappings ().get_hirid (),
- param.get_mappings ().get_hirid (), {});
+ TyTy::BaseGeneric *const_decl
+ = new TyTy::ConstParamType (param.get_name (), param.get_locus (),
+ specified_type,
+ param.get_mappings ().get_hirid (),
+ param.get_mappings ().get_hirid (),
+ {});
context->insert_type (generic_param->get_mappings (), const_decl);
TyTy::SubstitutionParamMapping p (*generic_param, const_decl);
#include "rust-immutable-name-resolution-context.h"
#include "rust-compile-base.h"
#include "rust-tyty-util.h"
+#include "rust-tyty.h"
#include "tree.h"
namespace Rust {
return;
}
- auto locus = expr.get_locus ();
- auto infer_ty_var = TyTy::TyVar::get_implicit_infer_var (locus);
-
- HirId next = mappings.get_next_hir_id ();
- infered = new TyTy::ConstType (TyTy::ConstType::ConstKind::Infer, "",
- infer_ty_var.get_tyty (), error_mark_node, {},
- locus, next, next, {});
-
- context->insert_implicit_type (infered->get_ref (), infered);
- mappings.insert_location (infered->get_ref (), locus);
+ TyTy::TyVar var
+ = TyTy::TyVar::get_implicit_const_infer_var (expr.get_locus ());
+ infered = var.get_tyty ();
}
void
tree capacity_value
= Compile::HIRCompileBase::query_compile_const_expr (ctx, capacity_type,
*capacity_expr);
- HirId size_id = capacity_expr->get_mappings ().get_hirid ();
- TyTy::ConstType *const_type
- = new TyTy::ConstType (TyTy::ConstType::ConstKind::Value, "", expected_ty,
- capacity_value, {}, capacity_expr->get_locus (),
- size_id, size_id);
+
+ // Create ConstValueType with ref == ty_ref (both pointing to capacity_expr)
+ // ty_ref gets updated during substitution via set_ty_ref()
+ HirId capacity_expr_id = capacity_expr->get_mappings ().get_hirid ();
+ auto const_type
+ = new TyTy::ConstValueType (capacity_value, expected_ty, capacity_expr_id,
+ capacity_expr_id);
+
+ // Insert the ConstValueType at its ref
+ context->insert_type (capacity_expr->get_mappings (),
+ const_type->as_base_type ());
+
infered
= new TyTy::ArrayType (expr.get_mappings ().get_hirid (), expr.get_locus (),
- const_type, TyTy::TyVar (element_type->get_ref ()));
+ TyTy::TyVar (
+ const_type->as_base_type ()->get_ty_ref ()),
+ TyTy::TyVar (element_type->get_ref ()));
}
// empty struct
#include "rust-hir-type-check-expr.h"
#include "rust-type-util.h"
#include "rust-immutable-name-resolution-context.h"
+#include "rust-tyty.h"
+#include "tree.h"
namespace Rust {
namespace Resolver {
auto &array_ty_ty = static_cast<TyTy::ArrayType &> (*parent);
parent_element_ty = array_ty_ty.get_element_type ();
auto capacity = array_ty_ty.get_capacity ();
- tree cap = capacity->get_value ();
+
+ tree cap = error_mark_node;
+ if (capacity->get_kind () != TyTy::TypeKind::CONST)
+ {
+ // Error case - capacity is not a const type
+ break;
+ }
+
+ auto *capacity_const = capacity->as_const_type ();
+ switch (capacity_const->const_kind ())
+ {
+ case TyTy::BaseConstType::ConstKind::Value:
+ {
+ const auto &const_value
+ = *static_cast<TyTy::ConstValueType *> (capacity);
+ cap = const_value.get_value ();
+ }
+ break;
+
+ case TyTy::BaseConstType::ConstKind::Decl:
+ case TyTy::BaseConstType::ConstKind::Infer:
+ case TyTy::BaseConstType::ConstKind::Error:
+ cap = error_mark_node;
+ break;
+ }
+
if (error_operand_p (cap))
{
rust_error_at (parent->get_locus (),
rust_assert (ok);
context->insert_type (type.get_size_expr ().get_mappings (), expected_ty);
- TyTy::ConstType *const_type = nullptr;
+ TyTy::BaseConstType *const_type = nullptr;
if (capacity_type->get_kind () == TyTy::TypeKind::CONST)
{
- const_type = static_cast<TyTy::ConstType *> (capacity_type);
+ const_type = capacity_type->as_const_type ();
unify_site (type.get_size_expr ().get_mappings ().get_hirid (),
TyTy::TyWithLocation (expected_ty),
- TyTy::TyWithLocation (const_type->get_ty (),
+ TyTy::TyWithLocation (const_type->get_specified_type (),
type.get_size_expr ().get_locus ()),
type.get_size_expr ().get_locus ());
}
type.get_size_expr ().get_locus ());
if (result->is<TyTy::ErrorType> ())
- {
- const_type
- = new TyTy::ConstType (TyTy::ConstType::ConstKind::Error, "",
- expected_ty, error_mark_node, {},
- type.get_size_expr ().get_locus (), size_id,
- size_id);
- }
+ const_type = new TyTy::ConstErrorType (expected_ty, size_id, size_id);
else
{
auto ctx = Compile::Context::get ();
= Compile::HIRCompileBase::query_compile_const_expr (
ctx, capacity_type, type.get_size_expr ());
- const_type = new TyTy::ConstType (TyTy::ConstType::ConstKind::Value,
- "", expected_ty, capacity_expr, {},
- type.get_size_expr ().get_locus (),
- size_id, size_id);
+ const_type = new TyTy::ConstValueType (capacity_expr, expected_ty,
+ size_id, size_id);
+ context->insert_type (type.get_size_expr ().get_mappings (),
+ const_type->as_base_type ());
}
}
translated
= new TyTy::ArrayType (type.get_mappings ().get_hirid (), type.get_locus (),
- const_type, TyTy::TyVar (element_type->get_ref ()));
+ TyTy::TyVar (
+ const_type->as_base_type ()->get_ty_ref ()),
+ TyTy::TyVar (element_type->get_ref ()));
}
void
}
void
-SubstMapperInternal::visit (TyTy::ConstType &type)
+SubstMapperInternal::visit (TyTy::ConstParamType &type)
{
resolved = type.handle_substitions (mappings);
}
+void
+SubstMapperInternal::visit (TyTy::ConstValueType &type)
+{
+ resolved = type.clone ();
+}
+
+void
+SubstMapperInternal::visit (TyTy::ConstInferType &type)
+{
+ resolved = type.clone ();
+}
+
+void
+SubstMapperInternal::visit (TyTy::ConstErrorType &type)
+{
+ resolved = type.clone ();
+}
+
void
SubstMapperInternal::visit (TyTy::PlaceholderType &type)
{
void visit (TyTy::ReferenceType &) override { rust_unreachable (); }
void visit (TyTy::PointerType &) override { rust_unreachable (); }
void visit (TyTy::ParamType &) override { rust_unreachable (); }
- void visit (TyTy::ConstType &) override { rust_unreachable (); }
+ void visit (TyTy::ConstParamType &) override { rust_unreachable (); }
+ void visit (TyTy::ConstValueType &) override { rust_unreachable (); }
+ void visit (TyTy::ConstInferType &) override { rust_unreachable (); }
+ void visit (TyTy::ConstErrorType &) override { rust_unreachable (); }
void visit (TyTy::StrType &) override { rust_unreachable (); }
void visit (TyTy::NeverType &) override { rust_unreachable (); }
void visit (TyTy::DynamicObjectType &) override { rust_unreachable (); }
void visit (TyTy::ReferenceType &type) override;
void visit (TyTy::PointerType &type) override;
void visit (TyTy::ParamType &type) override;
- void visit (TyTy::ConstType &type) override;
+ void visit (TyTy::ConstParamType &type) override;
+ void visit (TyTy::ConstValueType &type) override;
+ void visit (TyTy::ConstInferType &type) override;
+ void visit (TyTy::ConstErrorType &type) override;
void visit (TyTy::PlaceholderType &type) override;
void visit (TyTy::ProjectionType &type) override;
void visit (TyTy::ClosureType &type) override;
void visit (TyTy::ReferenceType &) override { rust_unreachable (); }
void visit (TyTy::PointerType &) override { rust_unreachable (); }
void visit (TyTy::ParamType &) override { rust_unreachable (); }
- void visit (TyTy::ConstType &) override { rust_unreachable (); }
+ void visit (TyTy::ConstParamType &) override { rust_unreachable (); }
+ void visit (TyTy::ConstValueType &) override { rust_unreachable (); }
+ void visit (TyTy::ConstInferType &) override { rust_unreachable (); }
+ void visit (TyTy::ConstErrorType &) override { rust_unreachable (); }
void visit (TyTy::StrType &) override { rust_unreachable (); }
void visit (TyTy::NeverType &) override { rust_unreachable (); }
void visit (TyTy::PlaceholderType &) override { rust_unreachable (); }
void visit (TyTy::ProjectionType &) override { rust_unreachable (); }
void visit (TyTy::DynamicObjectType &) override { rust_unreachable (); }
- void visit (TyTy::OpaqueType &type) override { rust_unreachable (); }
+ void visit (TyTy::OpaqueType &) override { rust_unreachable (); }
private:
SubstMapperFromExisting (TyTy::BaseType *concrete, TyTy::BaseType *receiver);
void visit (const TyTy::ReferenceType &) override {}
void visit (const TyTy::PointerType &) override {}
void visit (const TyTy::ParamType &) override {}
- void visit (const TyTy::ConstType &) override {}
+ void visit (const TyTy::ConstParamType &) override {}
+ void visit (const TyTy::ConstValueType &) override {}
+ void visit (const TyTy::ConstInferType &) override {}
+ void visit (const TyTy::ConstErrorType &) override {}
void visit (const TyTy::StrType &) override {}
void visit (const TyTy::NeverType &) override {}
void visit (const TyTy::PlaceholderType &) override {}
// remove the inference variable
context.clear_type (i.infer);
- delete i.infer;
+ // FIXME: Don't delete - result might point to this
+ // delete i.infer;
}
}
return result;
void visit (PlaceholderType &) override { rust_unreachable (); }
void visit (ProjectionType &) override { rust_unreachable (); }
void visit (DynamicObjectType &) override { rust_unreachable (); }
- void visit (ClosureType &type) override { rust_unreachable (); }
- void visit (OpaqueType &type) override { rust_unreachable (); }
- void visit (ConstType &type) override { rust_unreachable (); }
+ void visit (ClosureType &) override { rust_unreachable (); }
+ void visit (OpaqueType &) override { rust_unreachable (); }
+ void visit (ConstParamType &) override { rust_unreachable (); }
+ void visit (ConstValueType &) override { rust_unreachable (); }
+ void visit (ConstInferType &) override { rust_unreachable (); }
+ void visit (ConstErrorType &) override { rust_unreachable (); }
// tuple-structs
void visit (ADTType &type) override;
SubstitutionParamMapping
SubstitutionParamMapping::clone () const
{
- return SubstitutionParamMapping (generic,
- static_cast<ParamType *> (param->clone ()));
+ return SubstitutionParamMapping (generic, static_cast<BaseGeneric *> (
+ param->clone ()));
}
BaseGeneric *
}
else if (type.get_kind () == TyTy::TypeKind::CONST)
{
- param = static_cast<BaseGeneric *> (type.clone ());
+ rust_assert (param->get_kind () == TyTy::TypeKind::CONST);
+ auto *const_type = type.as_const_type ();
+ if (const_type->const_kind () == TyTy::BaseConstType::ConstKind::Decl)
+ param = static_cast<BaseGeneric *> (type.clone ());
+ else
+ param->set_ty_ref (type.get_ref ());
}
else if (param->get_kind () == TypeKind::PARAM)
{
}
else if (generic.get_kind () == HIR::GenericParam::GenericKind::CONST)
{
- if (!resolved->is<ConstType> ())
+ if (resolved->get_kind () != TyTy::TypeKind::CONST)
{
rich_location r (line_table, arg->get_locus ());
r.add_fixit_remove (arg->get_locus ());
// get the const generic specified type
const auto base_generic = param_mapping.get_param_ty ();
- rust_assert (base_generic->is<ConstType> ());
+ rust_assert (base_generic->get_kind () == TyTy::TypeKind::CONST);
const auto const_param
- = static_cast<const TyTy::ConstType *> (base_generic);
- auto specified_type = const_param->get_ty ();
+ = static_cast<const TyTy::ConstParamType *> (base_generic);
+ auto specified_type = const_param->get_specified_type ();
// validate this const generic is of the correct type
TyTy::BaseType *coereced_type = nullptr;
- if (expr_type->is<ConstType> ())
+ if (expr_type->get_kind () == TyTy::TypeKind::CONST)
{
- TyTy::ConstType *const_expr_type
- = static_cast<TyTy::ConstType *> (expr_type);
- TyTy::BaseType *const_value_type = const_expr_type->get_ty ();
+ auto const_expr_type = expr_type->as_const_type ();
+ auto const_value_type = const_expr_type->get_specified_type ();
coereced_type
= Resolver::coercion_site (expr.get_mappings ().get_hirid (),
TyTy::TyWithLocation (specified_type),
return SubstitutionArgumentMappings::error ();
TyTy::BaseType *const_value_ty = nullptr;
- if (expr_type->is<ConstType> ())
+ if (expr_type->get_kind () == TyTy::TypeKind::CONST)
const_value_ty = expr_type;
else
{
return SubstitutionArgumentMappings::error ();
}
+ // Use a fresh HirId to avoid conflicts with the expr's type
+ auto &global_mappings = Analysis::Mappings::get ();
+ HirId const_value_id = global_mappings.get_next_hir_id ();
const_value_ty
- = new TyTy::ConstType (TyTy::ConstType::ConstKind::Value, "",
- coereced_type, folded, {}, expr.get_locus (),
- expr.get_mappings ().get_hirid (),
- expr.get_mappings ().get_hirid (), {});
+ = new TyTy::ConstValueType (folded, coereced_type, const_value_id,
+ const_value_id, {});
+
+ // Insert the ConstValueType into the context so it can be looked up
+ auto context = Resolver::TypeCheckContext::get ();
+ context->insert_type (
+ Analysis::NodeMapping (0, 0, const_value_ty->get_ref (), 0),
+ const_value_ty);
}
mappings.emplace_back (¶m_mapping, const_value_ty);
}
else if (generic.get_kind () == HIR::GenericParam::GenericKind::CONST)
{
- const auto const_param = p.get_param_ty ();
- rust_assert (const_param->is<TyTy::ConstType> ());
- const auto &const_type
- = *static_cast<const TyTy::ConstType *> (const_param);
-
- TyVar infer_var
- = TyVar::get_implicit_const_infer_var (const_type, locus);
+ TyVar infer_var = TyVar::get_implicit_const_infer_var (locus);
args.emplace_back (&p, infer_var.get_tyty ());
argument_mappings[symbol] = infer_var.get_tyty ();
}
}
TyVar
-TyVar::get_implicit_const_infer_var (const ConstType &const_type,
- location_t locus)
+TyVar::get_implicit_const_infer_var (location_t locus)
{
auto &mappings = Analysis::Mappings::get ();
auto context = Resolver::TypeCheckContext::get ();
+ TyVar ty_infer = get_implicit_infer_var (locus);
HirId next = mappings.get_next_hir_id ();
- auto infer
- = new ConstType (ConstType::ConstKind::Infer, const_type.get_symbol (),
- const_type.get_ty (), error_mark_node,
- const_type.get_specified_bounds (), locus, next, next, {});
+ auto infer = new ConstInferType (ty_infer.get_tyty (), next, next, {});
context->insert_implicit_type (infer->get_ref (), infer);
mappings.insert_location (infer->get_ref (), locus);
static TyVar get_implicit_infer_var (location_t locus);
- static TyVar get_implicit_const_infer_var (const TyTy::ConstType &const_type,
- location_t locus);
+ static TyVar get_implicit_const_infer_var (location_t locus);
static TyVar subst_covariant_var (TyTy::BaseType *orig,
TyTy::BaseType *subst);
void visit (OpaqueType &type) override {}
- void visit (ConstType &type) override {}
+ void visit (TyTy::ConstParamType &) override {}
+ void visit (TyTy::ConstValueType &) override {}
+ void visit (TyTy::ConstInferType &) override {}
+ void visit (TyTy::ConstErrorType &) override {}
};
/** Per crate context for generic type variance analysis. */
virtual void visit (ReferenceType &type) = 0;
virtual void visit (PointerType &type) = 0;
virtual void visit (ParamType &type) = 0;
- virtual void visit (ConstType &type) = 0;
+ virtual void visit (ConstParamType &type) = 0;
+ virtual void visit (ConstValueType &type) = 0;
+ virtual void visit (ConstInferType &type) = 0;
+ virtual void visit (ConstErrorType &type) = 0;
virtual void visit (StrType &type) = 0;
virtual void visit (NeverType &type) = 0;
virtual void visit (PlaceholderType &type) = 0;
virtual void visit (const ReferenceType &type) = 0;
virtual void visit (const PointerType &type) = 0;
virtual void visit (const ParamType &type) = 0;
- virtual void visit (const ConstType &type) = 0;
+ virtual void visit (const ConstParamType &type) = 0;
+ virtual void visit (const ConstValueType &type) = 0;
+ virtual void visit (const ConstInferType &type) = 0;
+ virtual void visit (const ConstErrorType &type) = 0;
virtual void visit (const StrType &type) = 0;
virtual void visit (const NeverType &type) = 0;
virtual void visit (const PlaceholderType &type) = 0;
x = pr;
}
+ else if (x->get_kind () == TypeKind::CONST)
+ {
+ auto p = x->as_const_type ();
+ if (p->const_kind () == BaseConstType::ConstKind::Decl)
+ {
+ auto decl = static_cast<ConstParamType *> (p);
+ auto pr = decl->resolve ();
+ if (pr == x)
+ return pr;
+
+ x = pr;
+ }
+ else
+ {
+ return x;
+ }
+ }
else if (auto p = x->try_as<PlaceholderType> ())
{
if (!p->can_resolve ())
x = pr;
}
+ else if (x->get_kind () == TypeKind::CONST)
+ {
+ auto p = x->as_const_type ();
+ if (p->const_kind () == BaseConstType::ConstKind::Decl)
+ {
+ auto decl = static_cast<const ConstParamType *> (p);
+ auto pr = decl->resolve ();
+ if (pr == x)
+ return pr;
+
+ x = pr;
+ }
+ else
+ {
+ return x;
+ }
+ }
else if (auto p = x->try_as<const PlaceholderType> ())
{
if (!p->can_resolve ())
{
TyVar elm = arr->get_var_element_type ().monomorphized_clone ();
return new ArrayType (arr->get_ref (), arr->get_ty_ref (), ident.locus,
- arr->get_capacity (), elm,
+ arr->get_capacity_var (), elm,
arr->get_combined_refs ());
}
else if (auto slice = x->try_as<const SliceType> ())
{
const TyTy::BaseType *x = destructure ();
- if (x->is<ParamType> () || x->is<ProjectionType> ())
+ if (x->is<ParamType> () || x->is<ProjectionType> ()
+ || x->is<ConstParamType> ())
{
return false;
}
return false;
return closure->get_result_type ().is_concrete ();
}
- else if (auto const_type = x->try_as<const ConstType> ())
- {
- return const_type->get_value () != error_mark_node;
- }
else if (x->is<InferType> () || x->is<BoolType> () || x->is<CharType> ()
|| x->is<IntType> () || x->is<UintType> () || x->is<FloatType> ()
|| x->is<USizeType> () || x->is<ISizeType> () || x->is<NeverType> ()
std::string
ArrayType::as_string () const
{
- return "[" + get_element_type ()->as_string () + "; " + capacity->as_string ()
- + "]";
+ auto cap = get_capacity ();
+ std::string capacity_str = cap->as_string ();
+
+ return "[" + get_element_type ()->as_string () + "; " + capacity_str + "]";
}
bool
return element_type;
}
+BaseType *
+ArrayType::get_capacity () const
+{
+ return capacity.get_tyty ();
+}
+
BaseType *
ArrayType::clone () const
{
BaseType *concrete_cap
= Resolver::SubstMapperInternal::Resolve (cap, mappings);
rust_assert (concrete_cap->get_kind () == TyTy::TypeKind::CONST);
- ref->capacity = static_cast<TyTy::ConstType *> (concrete_cap);
+ ref->capacity = TyVar::subst_covariant_var (cap, concrete_cap);
return ref;
}
return is_trait_self;
}
-// ConstType
+static std::string
+generate_tree_str (tree value)
+{
+ char *buf = nullptr;
+ size_t size = 0;
-ConstType::ConstType (ConstKind kind, std::string symbol, TyTy::BaseType *ty,
- tree value,
- std::vector<TypeBoundPredicate> specified_bounds,
- location_t locus, HirId ref, HirId ty_ref,
- std::set<HirId> refs)
- : BaseGeneric (ref, ty_ref, KIND,
- {Resolver::CanonicalPath::new_seg (UNKNOWN_NODEID,
- symbol.empty () ? "<n/a>"
- : symbol),
+ FILE *stream = open_memstream (&buf, &size);
+ if (!stream)
+ return "<error>";
+
+ print_generic_stmt (stream, value, TDF_NONE);
+ fclose (stream);
+
+ std::string result = (buf ? std::string (buf, size) : "<error>");
+ free (buf);
+
+ if (!result.empty () && result.back () == '\n')
+ result.pop_back ();
+
+ return result;
+}
+
+// ---
+
+ConstParamType::ConstParamType (std::string symbol, location_t locus,
+ BaseType *type, HirId ref, HirId ty_ref,
+ std::set<HirId> refs)
+ : BaseConstType (type),
+ BaseGeneric (ref, ty_ref, KIND,
+ {Resolver::CanonicalPath::new_seg (UNKNOWN_NODEID, symbol),
locus},
- specified_bounds, refs),
- const_kind (kind), ty (ty), value (value), symbol (symbol)
+ {}, refs),
+ symbol (symbol)
{}
-void
-ConstType::accept_vis (TyVisitor &vis)
+BaseConstType::ConstKind
+ConstParamType::const_kind () const
{
- vis.visit (*this);
+ return BaseConstType::ConstKind::Decl;
+}
+
+std::string
+ConstParamType::get_symbol () const
+{
+ return symbol;
+}
+
+bool
+ConstParamType::can_resolve () const
+{
+ return get_ref () != get_ty_ref ();
+}
+
+BaseType *
+ConstParamType::resolve () const
+{
+ TyVar var (get_ty_ref ());
+ BaseType *r = var.get_tyty ();
+
+ while (r->get_kind () == TypeKind::CONST)
+ {
+ TyVar v (r->get_ty_ref ());
+ BaseType *n = v.get_tyty ();
+
+ // fix infinite loop
+ if (r == n)
+ break;
+
+ r = n;
+ }
+
+ if (r->get_kind () == TypeKind::CONST && (r->get_ref () == r->get_ty_ref ()))
+ {
+ auto *const_type = r->as_const_type ();
+ if (const_type->const_kind () != BaseConstType::ConstKind::Value)
+ return TyVar (r->get_ty_ref ()).get_tyty ();
+ }
+
+ return r;
}
void
-ConstType::accept_vis (TyConstVisitor &vis) const
+ConstParamType::accept_vis (TyVisitor &vis)
{
vis.visit (*this);
}
void
-ConstType::set_value (tree v)
+ConstParamType::accept_vis (TyConstVisitor &vis) const
{
- value = v;
- const_kind = ConstType::ConstKind::Value;
+ vis.visit (*this);
}
std::string
-ConstType::as_string () const
+ConstParamType::as_string () const
{
- return get_name ();
+ if (!can_resolve ())
+ {
+ return get_symbol () + " CONST_REF: " + std::to_string (get_ref ());
+ }
+
+ BaseType *lookup = resolve ();
+ // Avoid infinite recursion if resolve() returns this same type
+ if (lookup == this->as_base_type ())
+ {
+ return get_symbol () + " CONST_REF: " + std::to_string (get_ref ());
+ }
+
+ return get_symbol () + "=" + lookup->as_string ();
}
BaseType *
-ConstType::clone () const
+ConstParamType::clone () const
{
- return new ConstType (const_kind, symbol, ty, value, get_specified_bounds (),
- ident.locus, ref, ty_ref, get_combined_refs ());
+ return new ConstParamType (get_symbol (), ident.locus, specified_type,
+ get_ref (), get_ty_ref (), get_combined_refs ());
}
std::string
-ConstType::get_symbol () const
+ConstParamType::get_name () const
{
- return symbol;
+ if (!can_resolve ())
+ return get_symbol ();
+
+ BaseType *lookup = resolve ();
+ // Avoid infinite recursion if resolve() returns this same type
+ if (lookup == this->as_base_type ())
+ return get_symbol ();
+
+ return lookup->get_name ();
}
bool
-ConstType::can_resolve () const
+ConstParamType::is_equal (const BaseType &other) const
{
- return false;
+ if (get_kind () != other.get_kind ())
+ {
+ if (!can_resolve ())
+ return false;
+
+ return resolve ()->is_equal (other);
+ }
+
+ auto other_const = other.as_const_type ();
+ if (other_const->const_kind () != BaseConstType::ConstKind::Decl)
+ return false;
+
+ auto &other2 = static_cast<const ConstParamType &> (*other_const);
+ if (can_resolve () != other2.can_resolve ())
+ return false;
+
+ if (can_resolve ())
+ return Resolver::types_compatable (TyTy::TyWithLocation (resolve ()),
+ TyTy::TyWithLocation (other2.resolve ()),
+ ident.locus, false);
+
+ return get_symbol ().compare (other2.get_symbol ()) == 0;
}
BaseType *
-ConstType::resolve () const
+ConstParamType::handle_substitions (
+ SubstitutionArgumentMappings &subst_mappings)
{
- rust_unreachable ();
- return nullptr;
+ SubstitutionArg arg = SubstitutionArg::error ();
+ bool ok = subst_mappings.get_argument_for_symbol (this, &arg);
+ if (!ok || arg.is_error ())
+ return this;
+
+ ConstParamType *p = static_cast<ConstParamType *> (clone ());
+ const BaseType *resolved = arg.get_tyty ();
+
+ // this is the new subst that this needs to pass
+ p->set_ref (mappings.get_next_hir_id ());
+ p->set_ty_ref (resolved->get_ref ());
+
+ return p;
}
-static std::string
-generate_tree_str (tree value)
+// --- ConstValueType
+
+ConstValueType::ConstValueType (tree value, BaseType *type, HirId ref,
+ HirId ty_ref, std::set<HirId> refs)
+ : BaseType (ref, ty_ref, KIND,
+ {Resolver::CanonicalPath::create_empty (), UNKNOWN_LOCATION},
+ refs),
+ BaseConstType (type), folded_val (value)
+{}
+
+BaseConstType::ConstKind
+ConstValueType::const_kind () const
{
- char *buf = nullptr;
- size_t size = 0;
+ return BaseConstType::ConstKind::Value;
+}
- FILE *stream = open_memstream (&buf, &size);
- if (!stream)
- return "<error>";
+void
+ConstValueType::accept_vis (TyVisitor &vis)
+{
+ vis.visit (*this);
+}
- print_generic_stmt (stream, value, TDF_NONE);
- fclose (stream);
+void
+ConstValueType::accept_vis (TyConstVisitor &vis) const
+{
+ vis.visit (*this);
+}
- std::string result = (buf ? std::string (buf, size) : "<error>");
- free (buf);
+std::string
+ConstValueType::as_string () const
+{
+ return generate_tree_str (folded_val);
+}
- if (!result.empty () && result.back () == '\n')
- result.pop_back ();
+BaseType *
+ConstValueType::clone () const
+{
+ return new ConstValueType (folded_val, specified_type, get_ref (),
+ get_ty_ref (), get_combined_refs ());
+}
- return result;
+std::string
+ConstValueType::get_name () const
+{
+ return as_string ();
+}
+
+bool
+ConstValueType::is_equal (const BaseType &other) const
+{
+ if (get_kind () != other.get_kind ())
+ return false;
+
+ auto other_const = other.as_const_type ();
+ if (other_const->const_kind () != BaseConstType::ConstKind::Value)
+ return false;
+
+ auto &other2 = static_cast<const ConstValueType &> (*other_const);
+ return folded_val == other2.folded_val;
+}
+
+tree
+ConstValueType::get_value () const
+{
+ return folded_val;
+}
+
+// --- ConstInferType
+
+ConstInferType::ConstInferType (BaseType *type, HirId ref, HirId ty_ref,
+ std::set<HirId> refs)
+ : BaseType (ref, ty_ref, KIND,
+ {Resolver::CanonicalPath::create_empty (), UNKNOWN_LOCATION},
+ refs),
+ BaseConstType (type)
+{}
+
+BaseConstType::ConstKind
+ConstInferType::const_kind () const
+{
+ return BaseConstType::ConstKind::Infer;
+}
+
+void
+ConstInferType::accept_vis (TyVisitor &vis)
+{
+ vis.visit (*this);
+}
+
+void
+ConstInferType::accept_vis (TyConstVisitor &vis) const
+{
+ vis.visit (*this);
}
std::string
-ConstType::get_name () const
+ConstInferType::as_string () const
{
- if (value == error_mark_node)
- {
- switch (get_const_kind ())
- {
- case Rust::TyTy::ConstType::Decl:
- return "ConstType:<" + get_ty ()->get_name () + " " + get_symbol ()
- + ">";
+ return specified_type->get_name () + "-?";
+}
- case Rust::TyTy::ConstType::Infer:
- return "ConstType:<" + get_ty ()->get_name () + " ?" + ">";
+BaseType *
+ConstInferType::clone () const
+{
+ auto &mappings = Analysis::Mappings::get ();
+ auto context = Resolver::TypeCheckContext::get ();
- default:
- return "ConstType:<" + get_ty ()->get_name () + " - <error>" + ">";
- }
- }
+ ConstInferType *clone
+ = new ConstInferType (specified_type, mappings.get_next_hir_id (),
+ get_ty_ref (), get_combined_refs ());
- return generate_tree_str (value);
+ context->insert_type (Analysis::NodeMapping (mappings.get_current_crate (),
+ UNKNOWN_NODEID,
+ clone->get_ref (),
+ UNKNOWN_LOCAL_DEFID),
+ clone);
+ mappings.insert_location (clone->get_ref (),
+ mappings.lookup_location (get_ref ()));
+
+ clone->append_reference (get_ref ());
+
+ return clone;
+}
+
+std::string
+ConstInferType::get_name () const
+{
+ return as_string ();
}
bool
-ConstType::is_equal (const BaseType &other) const
+ConstInferType::is_equal (const BaseType &other) const
{
if (get_kind () != other.get_kind ())
- {
- return false;
- }
+ return false;
- const ConstType &rhs = static_cast<const ConstType &> (other);
- if (!get_ty ()->is_equal (*rhs.get_ty ()))
+ auto other_const = other.as_const_type ();
+ if (other_const->const_kind () != BaseConstType::ConstKind::Infer)
return false;
- tree lv = get_value ();
- tree rv = rhs.get_value ();
+ return get_ref () == other.get_ref ();
+}
+
+// --- ConstErrorType
+
+ConstErrorType::ConstErrorType (BaseType *type, HirId ref, HirId ty_ref,
+ std::set<HirId> refs)
+ : BaseType (ref, ty_ref, KIND,
+ {Resolver::CanonicalPath::create_empty (), UNKNOWN_LOCATION},
+ refs),
+ BaseConstType (type)
+{}
- return operand_equal_p (lv, rv, 0);
+BaseConstType::ConstKind
+ConstErrorType::const_kind () const
+{
+ return BaseConstType::ConstKind::Error;
}
-ConstType *
-ConstType::handle_substitions (SubstitutionArgumentMappings &mappings)
+void
+ConstErrorType::accept_vis (TyVisitor &vis)
{
- SubstitutionArg arg = SubstitutionArg::error ();
- bool found = mappings.get_argument_for_symbol (this, &arg);
- if (found && !arg.is_error ())
- {
- TyTy::BaseType *subst = arg.get_tyty ();
- rust_assert (subst->is<TyTy::ConstType> ());
- return static_cast<TyTy::ConstType *> (subst);
- }
+ vis.visit (*this);
+}
+
+void
+ConstErrorType::accept_vis (TyConstVisitor &vis) const
+{
+ vis.visit (*this);
+}
+
+std::string
+ConstErrorType::as_string () const
+{
+ return "<const_error>";
+}
+
+BaseType *
+ConstErrorType::clone () const
+{
+ return new ConstErrorType (specified_type, get_ref (), get_ty_ref (),
+ get_combined_refs ());
+}
+
+std::string
+ConstErrorType::get_name () const
+{
+ return as_string ();
+}
+
+bool
+ConstErrorType::is_equal (const BaseType &other) const
+{
+ if (get_kind () != other.get_kind ())
+ return false;
- return this;
+ auto other_const = other.as_const_type ();
+ return other_const->const_kind () == BaseConstType::ConstKind::Error;
}
// OpaqueType
class TyVisitor;
class TyConstVisitor;
+class BaseConstType;
class BaseType : public TypeBoundsMappings
{
public:
return static_cast<T *> (this);
}
+ // Helper to get BaseConstType interface for CONST types
+ // Overridden by const types that also inherit from BaseConstType
+ virtual BaseConstType *as_const_type () { return nullptr; }
+ virtual const BaseConstType *as_const_type () const { return nullptr; }
+
protected:
BaseType (HirId ref, HirId ty_ref, TypeKind kind, RustIdent ident,
std::set<HirId> refs = std::set<HirId> ());
std::string symbol;
};
-class ConstType : public BaseGeneric
+class BaseConstType
{
public:
static constexpr auto KIND = TypeKind::CONST;
Error
};
- ConstType (ConstKind kind, std::string symbol, TyTy::BaseType *ty, tree value,
- std::vector<TypeBoundPredicate> specified_bounds, location_t locus,
- HirId ref, HirId ty_ref,
- std::set<HirId> refs = std::set<HirId> ());
+ virtual ConstKind const_kind () const = 0;
- void accept_vis (TyVisitor &vis) override;
- void accept_vis (TyConstVisitor &vis) const override;
+ BaseType *get_specified_type () const { return specified_type; }
- ConstKind get_const_kind () const { return const_kind; }
- TyTy::BaseType *get_ty () const { return ty; }
- tree get_value () const { return value; }
+ // Helper to get BaseType interface (all const types also inherit BaseType)
+ // This must be implemented by concrete classes since BaseConstType doesn't
+ // inherit from BaseType, but all concrete const types do.
+ virtual BaseType *as_base_type () = 0;
+ virtual const BaseType *as_base_type () const = 0;
- void set_value (tree value);
+protected:
+ BaseConstType (BaseType *type) : specified_type (type) {}
- std::string as_string () const override;
+ BaseType *specified_type;
+};
- BaseType *clone () const final override;
+class ConstParamType : public BaseConstType, public BaseGeneric
+{
+public:
+ ConstParamType (std::string symbol, location_t locus, BaseType *type,
+ HirId ref, HirId ty_ref,
+ std::set<HirId> refs = std::set<HirId> ());
+
+ ConstKind const_kind () const override final;
std::string get_symbol () const override final;
BaseType *resolve () const override final;
+ void accept_vis (TyVisitor &vis) override;
+ void accept_vis (TyConstVisitor &vis) const override;
+
+ std::string as_string () const override;
+
+ BaseType *clone () const final override;
std::string get_name () const override final;
bool is_equal (const BaseType &other) const override;
- ConstType *handle_substitions (SubstitutionArgumentMappings &mappings);
+ BaseType *handle_substitions (SubstitutionArgumentMappings &mappings);
+
+ BaseType *as_base_type () override { return static_cast<BaseType *> (this); }
+ const BaseType *as_base_type () const override
+ {
+ return static_cast<const BaseType *> (this);
+ }
+
+ BaseConstType *as_const_type () override { return this; }
+ const BaseConstType *as_const_type () const override { return this; }
private:
- ConstKind const_kind;
- TyTy::BaseType *ty;
- tree value;
std::string symbol;
};
+class ConstValueType : public BaseType, public BaseConstType
+{
+public:
+ static constexpr auto KIND = TypeKind::CONST;
+
+ ConstValueType (tree value, BaseType *type, HirId ref, HirId ty_ref,
+ std::set<HirId> refs = std::set<HirId> ());
+
+ ConstKind const_kind () const override final;
+
+ void accept_vis (TyVisitor &vis) override;
+ void accept_vis (TyConstVisitor &vis) const override;
+
+ std::string as_string () const override;
+
+ BaseType *clone () const final override;
+ std::string get_name () const override final;
+
+ bool is_equal (const BaseType &other) const override;
+
+ tree get_value () const;
+
+ BaseType *as_base_type () override { return static_cast<BaseType *> (this); }
+ const BaseType *as_base_type () const override
+ {
+ return static_cast<const BaseType *> (this);
+ }
+
+ BaseConstType *as_const_type () override { return this; }
+ const BaseConstType *as_const_type () const override { return this; }
+
+private:
+ tree folded_val;
+};
+
+class ConstInferType : public BaseType, public BaseConstType
+{
+public:
+ static constexpr auto KIND = TypeKind::CONST;
+
+ ConstInferType (BaseType *type, HirId ref, HirId ty_ref,
+ std::set<HirId> refs = std::set<HirId> ());
+
+ ConstKind const_kind () const override final;
+
+ void accept_vis (TyVisitor &vis) override;
+ void accept_vis (TyConstVisitor &vis) const override;
+
+ std::string as_string () const override;
+
+ BaseType *clone () const final override;
+ std::string get_name () const override final;
+
+ bool is_equal (const BaseType &other) const override;
+
+ BaseType *as_base_type () override { return static_cast<BaseType *> (this); }
+ const BaseType *as_base_type () const override
+ {
+ return static_cast<const BaseType *> (this);
+ }
+
+ BaseConstType *as_const_type () override { return this; }
+ const BaseConstType *as_const_type () const override { return this; }
+};
+
+class ConstErrorType : public BaseType, public BaseConstType
+{
+public:
+ static constexpr auto KIND = TypeKind::CONST;
+
+ ConstErrorType (BaseType *type, HirId ref, HirId ty_ref,
+ std::set<HirId> refs = std::set<HirId> ());
+
+ ConstKind const_kind () const override final;
+
+ void accept_vis (TyVisitor &vis) override;
+ void accept_vis (TyConstVisitor &vis) const override;
+
+ std::string as_string () const override;
+
+ BaseType *clone () const final override;
+ std::string get_name () const override final;
+
+ bool is_equal (const BaseType &other) const override;
+
+ BaseType *as_base_type () override { return static_cast<BaseType *> (this); }
+ const BaseType *as_base_type () const override
+ {
+ return static_cast<const BaseType *> (this);
+ }
+
+ BaseConstType *as_const_type () override { return this; }
+ const BaseConstType *as_const_type () const override { return this; }
+};
+
class OpaqueType : public BaseType
{
public:
public:
static constexpr auto KIND = TypeKind::ARRAY;
- ArrayType (HirId ref, location_t locus, ConstType *capacity, TyVar base,
+ ArrayType (HirId ref, location_t locus, TyVar capacity, TyVar base,
std::set<HirId> refs = std::set<HirId> ())
: BaseType (ref, ref, TypeKind::ARRAY,
{Resolver::CanonicalPath::create_empty (), locus}, refs),
element_type (base), capacity (capacity)
{}
- ArrayType (HirId ref, HirId ty_ref, location_t locus, ConstType *capacity,
+ ArrayType (HirId ref, HirId ty_ref, location_t locus, TyVar capacity,
TyVar base, std::set<HirId> refs = std::set<HirId> ())
: BaseType (ref, ty_ref, TypeKind::ARRAY,
{Resolver::CanonicalPath::create_empty (), locus}, refs),
BaseType *clone () const final override;
- ConstType *get_capacity () const { return capacity; }
+ BaseType *get_capacity () const;
+ const TyVar &get_capacity_var () const { return capacity; }
ArrayType *handle_substitions (SubstitutionArgumentMappings &mappings);
private:
TyVar element_type;
- ConstType *capacity;
+ TyVar capacity;
};
class SliceType : public BaseType
b->append_reference (resolved->get_ref ());
b->append_reference (o->get_ref ());
- bool result_resolved = resolved->get_kind () != TyTy::TypeKind::INFER;
- bool result_is_infer_var = resolved->get_kind () == TyTy::TypeKind::INFER;
- bool results_is_non_general_infer_var
- = (result_is_infer_var
- && (static_cast<TyTy::InferType *> (resolved))->get_infer_kind ()
- != TyTy::InferType::GENERAL);
- if (result_resolved || results_is_non_general_infer_var)
+ if (resolved->get_kind () != TyTy::TypeKind::CONST)
{
- for (auto &ref : resolved->get_combined_refs ())
+ bool result_resolved = resolved->get_kind () != TyTy::TypeKind::INFER;
+ bool result_is_infer_var = resolved->get_kind () == TyTy::TypeKind::INFER;
+ bool results_is_non_general_infer_var
+ = (result_is_infer_var
+ && (static_cast<TyTy::InferType *> (resolved))->get_infer_kind ()
+ != TyTy::InferType::GENERAL);
+ if (result_resolved || results_is_non_general_infer_var)
{
- TyTy::BaseType *ref_tyty = nullptr;
- bool ok = context.lookup_type (ref, &ref_tyty);
- if (!ok)
- continue;
-
- // if any of the types are inference variables lets fix them
- if (ref_tyty->is<TyTy::InferType> ())
- context.insert_implicit_type (ref, resolved);
- else if (resolved->is<TyTy::ConstType> ()
- && ref_tyty->is<TyTy::ConstType> ())
+ for (auto &ref : resolved->get_combined_refs ())
{
- auto &const_expr = *static_cast<TyTy::ConstType *> (resolved);
- if (const_expr.get_const_kind ()
- == TyTy::ConstType::ConstKind::Value)
+ TyTy::BaseType *ref_tyty = nullptr;
+ bool ok = context.lookup_type (ref, &ref_tyty);
+ if (!ok)
+ continue;
+
+ // if any of the types are inference variables lets fix them
+ if (ref_tyty->is<TyTy::InferType> ())
+ context.insert_implicit_type (ref, resolved);
+ }
+ }
+ }
+ else
+ {
+ auto base_const = resolved->as_const_type ();
+ if (base_const->const_kind () == TyTy::BaseConstType::ConstKind::Value)
+ {
+ rust_debug ("UnifyRules::commit const value, resolved_ref=%u "
+ "resolved_ty_ref=%u combined_refs.size=%zu",
+ resolved->get_ref (), resolved->get_ty_ref (),
+ resolved->get_combined_refs ().size ());
+
+ for (auto &ref : resolved->get_combined_refs ())
+ {
+ TyTy::BaseType *ref_tyty = nullptr;
+ bool ok = context.lookup_type (ref, &ref_tyty);
+ if (!ok)
+ continue;
+ if (ref_tyty->get_kind () != TyTy::TypeKind::CONST)
+ continue;
+
+ auto ref_base_const = ref_tyty->as_const_type ();
+ if (ref_base_const->const_kind ()
+ == TyTy::BaseConstType::ConstKind::Infer
+ || ref_base_const->const_kind ()
+ == TyTy::BaseConstType::ConstKind::Decl)
{
+ rust_debug (" committing to ref=%u kind=%d", ref,
+ (int) ref_base_const->const_kind ());
context.insert_implicit_type (ref, resolved);
}
}
// set the rtype now to the new inference var
ltype = i;
}
- else if (ltype->is<TyTy::ConstType> () && rtype->is<TyTy::ConstType> ())
+ else if (ltype->get_kind () == TyTy::TypeKind::CONST
+ && rtype->get_kind () == TyTy::TypeKind::CONST)
{
- const auto &lhs = *static_cast<TyTy::ConstType *> (ltype);
- const auto &rhs = *static_cast<TyTy::ConstType *> (rtype);
+ const auto &lhs = *ltype->as_const_type ();
+ const auto &rhs = *rtype->as_const_type ();
bool both_are_decls
- = lhs.get_const_kind () == TyTy::ConstType::ConstKind::Decl
- && rhs.get_const_kind () == TyTy::ConstType::ConstKind::Decl;
+ = lhs.const_kind () == TyTy::BaseConstType::ConstKind::Decl
+ && rhs.const_kind () == TyTy::BaseConstType::ConstKind::Decl;
bool have_decls
- = lhs.get_const_kind () == TyTy::ConstType::ConstKind::Decl
- || rhs.get_const_kind () == TyTy::ConstType::ConstKind::Decl;
+ = lhs.const_kind () == TyTy::BaseConstType::ConstKind::Decl
+ || rhs.const_kind () == TyTy::BaseConstType::ConstKind::Decl;
if (have_decls && !both_are_decls)
{
- if (lhs.get_const_kind () == TyTy::ConstType::ConstKind::Decl)
+ if (lhs.const_kind () == TyTy::BaseConstType::ConstKind::Decl)
{
TyTy::TyVar iv = TyTy::TyVar::get_implicit_const_infer_var (
- lhs, lhs.get_locus ());
+ lhs.as_base_type ()->get_locus ());
ltype = iv.get_tyty ();
}
- else if (rhs.get_const_kind ()
- == TyTy::ConstType::ConstKind::Decl)
+ else if (rhs.const_kind ()
+ == TyTy::BaseConstType::ConstKind::Decl)
{
TyTy::TyVar iv = TyTy::TyVar::get_implicit_const_infer_var (
- rhs, rhs.get_locus ());
+ rhs.as_base_type ()->get_locus ());
rtype = iv.get_tyty ();
}
}
}
}
- if ((ltype->is<TyTy::ConstType> () || rtype->is<TyTy::ConstType> ())
- && !(ltype->is<TyTy::ConstType> () && rtype->is<TyTy::ConstType> ()))
- {
- if (ltype->is<TyTy::ConstType> ())
- {
- auto const_type = static_cast<TyTy::ConstType *> (ltype);
- ltype = const_type->get_ty ();
- }
- else if (rtype->is<TyTy::ConstType> ())
- {
- auto const_type = static_cast<TyTy::ConstType *> (rtype);
- rtype = const_type->get_ty ();
- }
- }
-
switch (ltype->get_kind ())
{
case TyTy::INFER:
return expect_opaque (static_cast<TyTy::OpaqueType *> (ltype), rtype);
case TyTy::CONST:
- return expect_const (static_cast<TyTy::ConstType *> (ltype), rtype);
+ return expect_const (ltype->as_const_type (), rtype);
case TyTy::ERROR:
return unify_error_type_node ();
if (element_unify->get_kind () == TyTy::TypeKind::ERROR)
return unify_error_type_node ();
+ auto ltype_cap = ltype->get_capacity ();
+ auto rtype_cap = type.get_capacity ();
+
+ // If either capacity is not a const type, return error
+ if (ltype_cap->get_kind () != TyTy::TypeKind::CONST
+ || rtype_cap->get_kind () != TyTy::TypeKind::CONST)
+ return unify_error_type_node ();
+
bool save_emit_error = emit_error;
emit_error = false;
TyTy::BaseType *capacity_unify
- = resolve_subtype (TyTy::TyWithLocation (ltype->get_capacity ()),
- TyTy::TyWithLocation (type.get_capacity ()));
+ = resolve_subtype (TyTy::TyWithLocation (ltype_cap),
+ TyTy::TyWithLocation (rtype_cap));
emit_error = save_emit_error;
if (capacity_unify->get_kind () != TyTy::TypeKind::CONST)
return unify_error_type_node ();
- TyTy::ConstType *capacity_type_unify
- = static_cast<TyTy::ConstType *> (capacity_unify);
- return new TyTy::ArrayType (type.get_ref (), type.get_ty_ref (),
- type.get_ident ().locus,
- capacity_type_unify,
- TyTy::TyVar (element_unify->get_ref ()));
+ auto capacity_type_unify = capacity_unify->as_const_type ();
+ if (capacity_type_unify->const_kind ()
+ == TyTy::BaseConstType::ConstKind::Error)
+ return unify_error_type_node ();
+
+ return new TyTy::ArrayType (
+ type.get_ref (), type.get_ty_ref (), type.get_ident ().locus,
+ TyTy::TyVar (capacity_type_unify->as_base_type ()->get_ref ()),
+ TyTy::TyVar (element_unify->get_ref ()));
}
break;
}
TyTy::BaseType *
-UnifyRules::expect_const (TyTy::ConstType *ltype, TyTy::BaseType *rtype)
+UnifyRules::expect_const (TyTy::BaseConstType *ltype, TyTy::BaseType *rtype)
{
if (rtype->get_kind () != TyTy::TypeKind::CONST)
return unify_error_type_node ();
- TyTy::ConstType &lhs = *ltype;
- TyTy::ConstType &rhs = *static_cast<TyTy::ConstType *> (rtype);
+ auto &lhs = *ltype;
+ auto &rhs = *rtype->as_const_type ();
- auto res = resolve_subtype (TyTy::TyWithLocation (lhs.get_ty ()),
- TyTy::TyWithLocation (rhs.get_ty ()));
- if (res->get_kind () == TyTy::TypeKind::ERROR)
- return unify_error_type_node ();
+ // Handle error types early
+ if (lhs.const_kind () == TyTy::BaseConstType::ConstKind::Error
+ || rhs.const_kind () == TyTy::BaseConstType::ConstKind::Error)
+ {
+ auto lhs_base = ltype->as_base_type ();
+ return new TyTy::ConstErrorType (lhs.get_specified_type (),
+ lhs_base->get_ref (),
+ lhs_base->get_ty_ref (),
+ lhs_base->get_combined_refs ());
+ }
- tree lv = lhs.get_value ();
- tree rv = rhs.get_value ();
+ // Try to resolve Decl types (ConstParamType)
+ TyTy::BaseConstType *resolved_lhs = &lhs;
+ TyTy::BaseConstType *resolved_rhs = &rhs;
- if (error_operand_p (lv) && error_operand_p (rv))
+ if (lhs.const_kind () == TyTy::BaseConstType::ConstKind::Decl)
{
- // this is only allowed for some silly senarios like:
- // gcc/testsuite/rust/compile/issue-const_generics_5.rs
- if (lhs.get_const_kind () == rhs.get_const_kind ())
+ auto *param = static_cast<TyTy::ConstParamType *> (&lhs);
+ if (param->can_resolve ())
{
- return new TyTy::ConstType (lhs.get_const_kind (), lhs.get_symbol (),
- res, error_mark_node,
- lhs.get_specified_bounds (),
- lhs.get_locus (), lhs.get_ref (),
- lhs.get_ty_ref (),
- lhs.get_combined_refs ());
+ auto *resolved = param->resolve ();
+ if (resolved->get_kind () == TyTy::TypeKind::CONST)
+ resolved_lhs = resolved->as_const_type ();
}
-
- return unify_error_type_node ();
}
- bool equal = operand_equal_p (lv, rv, 0);
- if (equal)
+ if (rhs.const_kind () == TyTy::BaseConstType::ConstKind::Decl)
{
- return new TyTy::ConstType (TyTy::ConstType::ConstKind::Value,
- lhs.get_symbol (), res, lv,
- lhs.get_specified_bounds (), lhs.get_locus (),
- lhs.get_ref (), lhs.get_ty_ref (),
- lhs.get_combined_refs ());
+ auto *param = static_cast<TyTy::ConstParamType *> (&rhs);
+ if (param->can_resolve ())
+ {
+ auto *resolved = param->resolve ();
+ if (resolved->get_kind () == TyTy::TypeKind::CONST)
+ resolved_rhs = resolved->as_const_type ();
+ }
}
- if (lhs.get_const_kind () == TyTy::ConstType::Infer && !error_operand_p (rv))
+ auto res = resolve_subtype (
+ TyTy::TyWithLocation (resolved_lhs->get_specified_type ()),
+ TyTy::TyWithLocation (resolved_rhs->get_specified_type ()));
+ if (res->get_kind () == TyTy::TypeKind::ERROR)
+ return unify_error_type_node ();
+
+ if (resolved_lhs->const_kind () == TyTy::BaseConstType::ConstKind::Value
+ && resolved_rhs->const_kind () == TyTy::BaseConstType::ConstKind::Value)
{
- lhs.set_value (rv);
- return new TyTy::ConstType (TyTy::ConstType::ConstKind::Value,
- lhs.get_symbol (), res, rv,
- lhs.get_specified_bounds (), lhs.get_locus (),
- lhs.get_ref (), lhs.get_ty_ref (),
- lhs.get_combined_refs ());
+ auto vlhs = static_cast<TyTy::ConstValueType &> (*resolved_lhs);
+ auto vrhs = static_cast<TyTy::ConstValueType &> (*resolved_rhs);
+ tree lv = vlhs.get_value ();
+ tree rv = vrhs.get_value ();
+
+ bool ok = operand_equal_p (lv, rv, 0);
+ if (!ok)
+ return unify_error_type_node ();
+ else
+ {
+ auto lhs_base = resolved_lhs->as_base_type ();
+ return new TyTy::ConstValueType (lv, res, lhs_base->get_ref (),
+ lhs_base->get_ty_ref (),
+ lhs_base->get_combined_refs ());
+ }
}
- else if (rhs.get_const_kind () == TyTy::ConstType::Infer
- && !error_operand_p (lv))
+ else if (resolved_lhs->const_kind () == TyTy::BaseConstType::ConstKind::Infer
+ && resolved_rhs->const_kind ()
+ == TyTy::BaseConstType::ConstKind::Value)
+ return resolved_rhs->as_base_type ();
+ else if (resolved_rhs->const_kind () == TyTy::BaseConstType::ConstKind::Infer
+ && resolved_lhs->const_kind ()
+ == TyTy::BaseConstType::ConstKind::Value)
+ return resolved_lhs->as_base_type ();
+ else if (resolved_lhs->const_kind () == TyTy::BaseConstType::ConstKind::Infer
+ && resolved_rhs->const_kind ()
+ == TyTy::BaseConstType::ConstKind::Infer)
+ return resolved_lhs->as_base_type ();
+ else if (resolved_lhs->const_kind () == TyTy::BaseConstType::ConstKind::Decl
+ || resolved_rhs->const_kind ()
+ == TyTy::BaseConstType::ConstKind::Decl)
{
- rhs.set_value (lv);
- return new TyTy::ConstType (TyTy::ConstType::ConstKind::Value,
- rhs.get_symbol (), res, lv,
- rhs.get_specified_bounds (), rhs.get_locus (),
- rhs.get_ref (), rhs.get_ty_ref (),
- rhs.get_combined_refs ());
+ // If we still have unresolved Decl after trying to resolve, unify with it
+ // This allows const inference to work
+ if (resolved_lhs->const_kind () == TyTy::BaseConstType::ConstKind::Decl
+ && resolved_rhs->const_kind ()
+ != TyTy::BaseConstType::ConstKind::Decl)
+ return resolved_rhs->as_base_type ();
+ else if (resolved_rhs->const_kind ()
+ == TyTy::BaseConstType::ConstKind::Decl
+ && resolved_lhs->const_kind ()
+ != TyTy::BaseConstType::ConstKind::Decl)
+ return resolved_lhs->as_base_type ();
+ // Both are Decl - return lhs
+ return resolved_lhs->as_base_type ();
}
return unify_error_type_node ();
TyTy::BaseType *rtype);
TyTy::BaseType *expect_opaque (TyTy::OpaqueType *ltype,
TyTy::BaseType *rtype);
- TyTy::BaseType *expect_const (TyTy::ConstType *ltype, TyTy::BaseType *rtype);
+ TyTy::BaseType *expect_const (TyTy::BaseConstType *ltype,
+ TyTy::BaseType *rtype);
private:
UnifyRules (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,