}
}
- TyTy::SubstitutionArgumentMappings infer_arguments (std::move (subst_args),
- {}, locus,
- param_subst_cb);
+ TyTy::SubstitutionArgumentMappings infer_arguments (
+ std::move (subst_args), {},
+ TyTy::SubstitutionArgumentMappings::regions_from_nullable_args (args),
+ locus, param_subst_cb);
TyTy::BaseType *impl_self_infer
= (!associated_self->is_concrete ())
? SubstMapperInternal::Resolve (associated_self, infer_arguments)
}
TyTy::SubstitutionArgumentMappings associated_type_args (
- std::move (associated_arguments), {}, locus);
+ std::move (associated_arguments), {},
+ TyTy::SubstitutionArgumentMappings::regions_from_nullable_args (args),
+ locus);
auto &impl_items = impl->get_impl_items ();
for (auto &impl_item : impl_items)
infered = new TyTy::ReferenceType (expr_mappings.get_hirid (),
TyTy::TyVar (base->get_ref ()),
- Mutability::Imm);
+ Mutability::Imm,
+ TyTy::Region::make_static ());
}
break;
infered = new TyTy::ReferenceType (expr_mappings.get_hirid (),
TyTy::TyVar (array->get_ref ()),
- Mutability::Imm);
+ Mutability::Imm,
+ TyTy::Region::make_static ());
}
break;
void
TypeCheckBase::resolve_generic_params (
- const std::vector<std::unique_ptr<HIR::GenericParam> > &generic_params,
+ const std::vector<std::unique_ptr<HIR::GenericParam>> &generic_params,
std::vector<TyTy::SubstitutionParamMapping> &substitutions)
{
for (auto &generic_param : generic_params)
{
- switch (generic_param.get ()->get_kind ())
+ switch (generic_param->get_kind ())
{
- case HIR::GenericParam::GenericKind::LIFETIME:
- // FIXME: Skipping Lifetime completely until better
- // handling.
+ case HIR::GenericParam::GenericKind::LIFETIME: {
+ auto lifetime_param
+ = static_cast<HIR::LifetimeParam &> (*generic_param);
+ auto lifetime = lifetime_param.get_lifetime ();
+ rust_assert (lifetime.get_lifetime_type ()
+ == AST::Lifetime::LifetimeType::NAMED);
+ context->get_lifetime_resolver ().insert_mapping (
+ context->intern_lifetime (lifetime));
+ }
+
break;
case HIR::GenericParam::GenericKind::CONST: {
const TyTy::SubstitutionParamMapping *param_ref = &adt->get_substs ().at (0);
subst_mappings.push_back (TyTy::SubstitutionArg (param_ref, unified));
- TyTy::SubstitutionArgumentMappings subst (subst_mappings, {},
- expr.get_locus ());
+ TyTy::SubstitutionArgumentMappings subst (
+ subst_mappings, {}, adt->get_substitution_arguments ().get_regions (),
+ expr.get_locus ());
infered = SubstMapperInternal::Resolve (adt, subst);
}
const TyTy::SubstitutionParamMapping *param_ref = &adt->get_substs ().at (0);
subst_mappings.push_back (TyTy::SubstitutionArg (param_ref, from_ty));
- TyTy::SubstitutionArgumentMappings subst (subst_mappings, {},
- expr.get_locus ());
+ TyTy::SubstitutionArgumentMappings subst (
+ subst_mappings, {}, adt->get_substitution_arguments ().get_regions (),
+ expr.get_locus ());
infered = SubstMapperInternal::Resolve (adt, subst);
}
const TyTy::SubstitutionParamMapping *param_ref = &adt->get_substs ().at (0);
subst_mappings.push_back (TyTy::SubstitutionArg (param_ref, from_ty));
- TyTy::SubstitutionArgumentMappings subst (subst_mappings, {},
- expr.get_locus ());
+ TyTy::SubstitutionArgumentMappings subst (
+ subst_mappings, {}, adt->get_substitution_arguments ().get_regions (),
+ expr.get_locus ());
infered = SubstMapperInternal::Resolve (adt, subst);
}
const TyTy::SubstitutionParamMapping *param_ref = &adt->get_substs ().at (0);
subst_mappings.push_back (TyTy::SubstitutionArg (param_ref, unified));
- TyTy::SubstitutionArgumentMappings subst (subst_mappings, {},
- expr.get_locus ());
+ TyTy::SubstitutionArgumentMappings subst (
+ subst_mappings, {}, adt->get_substitution_arguments ().get_regions (),
+ expr.get_locus ());
infered = SubstMapperInternal::Resolve (adt, subst);
}
if (resolved_candidate.is_impl_candidate ())
{
- auto infer_arguments = TyTy::SubstitutionArgumentMappings::error ();
+ auto infer_arguments = TyTy::SubstitutionArgumentMappings::empty ();
+ infer_arguments.get_mut_regions ()
+ = fn->get_used_arguments ().get_regions ();
HIR::ImplBlock &impl = *resolved_candidate.item.impl.parent;
TyTy::BaseType *impl_self_infer
= TypeCheckItem::ResolveImplBlockSelfWithInference (impl,
void
TypeCheckTopLevelExternItem::visit (HIR::ExternalFunctionItem &function)
{
+ auto binder_pin = context->push_clean_lifetime_resolver ();
+
std::vector<TyTy::SubstitutionParamMapping> substitutions;
if (function.has_generics ())
{
switch (generic_param.get ()->get_kind ())
{
case HIR::GenericParam::GenericKind::LIFETIME:
+ context->intern_and_insert_lifetime (
+ static_cast<HIR::LifetimeParam &> (*generic_param)
+ .get_lifetime ());
+ // TODO: handle bounds
+ break;
case HIR::GenericParam::GenericKind::CONST:
// FIXME: Skipping Lifetime and Const completely until better
// handling.
function.get_item_name ().as_string ()),
function.get_locus ()};
- auto fnType = new TyTy::FnType (function.get_mappings ().get_hirid (),
- function.get_mappings ().get_defid (),
- function.get_item_name ().as_string (), ident,
- flags, parent.get_abi (), std::move (params),
- ret_type, std::move (substitutions));
+ auto fnType = new TyTy::FnType (
+ function.get_mappings ().get_hirid (),
+ function.get_mappings ().get_defid (),
+ function.get_item_name ().as_string (), ident, flags, parent.get_abi (),
+ std::move (params), ret_type, std::move (substitutions),
+ TyTy::SubstitutionArgumentMappings::empty (
+ context->get_lifetime_resolver ().get_num_bound_regions ()));
context->insert_type (function.get_mappings (), fnType);
resolved = fnType;
void
TypeCheckImplItem::visit (HIR::Function &function)
{
+ auto binder_pin = context->push_lifetime_binder ();
+
if (function.has_generics ())
resolve_generic_params (function.get_generic_params (), substitutions);
self_type = self->clone ();
break;
- case HIR::SelfParam::IMM_REF:
- self_type = new TyTy::ReferenceType (
- self_param.get_mappings ().get_hirid (),
- TyTy::TyVar (self->get_ref ()), Mutability::Imm);
+ case HIR::SelfParam::IMM_REF: {
+ auto region = context->lookup_and_resolve_lifetime (
+ self_param.get_lifetime ());
+ if (!region.has_value ())
+ {
+ rust_inform (self_param.get_locus (),
+ "failed to resolve lifetime");
+ region = TyTy::Region::make_anonymous (); // FIXME
+ }
+ self_type = new TyTy::ReferenceType (
+ self_param.get_mappings ().get_hirid (),
+ TyTy::TyVar (self->get_ref ()), Mutability::Imm,
+ region.value ());
+ }
break;
- case HIR::SelfParam::MUT_REF:
- self_type = new TyTy::ReferenceType (
- self_param.get_mappings ().get_hirid (),
- TyTy::TyVar (self->get_ref ()), Mutability::Mut);
+ case HIR::SelfParam::MUT_REF: {
+ auto region = context->lookup_and_resolve_lifetime (
+ self_param.get_lifetime ());
+ if (!region.has_value ())
+ {
+ rust_error_at (self_param.get_locus (),
+ "failed to resolve lifetime");
+ return;
+ }
+ self_type = new TyTy::ReferenceType (
+ self_param.get_mappings ().get_hirid (),
+ TyTy::TyVar (self->get_ref ()), Mutability::Mut,
+ region.value ());
+ }
break;
default:
rust_assert (ok);
RustIdent ident{*canonical_path, function.get_locus ()};
- auto fnType
- = new TyTy::FnType (function.get_mappings ().get_hirid (),
- function.get_mappings ().get_defid (),
- function.get_function_name ().as_string (), ident,
- function.is_method ()
- ? TyTy::FnType::FNTYPE_IS_METHOD_FLAG
+ auto fnType = new TyTy::FnType (
+ function.get_mappings ().get_hirid (),
+ function.get_mappings ().get_defid (),
+ function.get_function_name ().as_string (), ident,
+ function.is_method () ? TyTy::FnType::FNTYPE_IS_METHOD_FLAG
: TyTy::FnType::FNTYPE_DEFAULT_FLAGS,
- ABI::RUST, std::move (params), ret_type,
- std::move (substitutions));
+ ABI::RUST, std::move (params), ret_type, std::move (substitutions),
+ TyTy::SubstitutionArgumentMappings::empty (
+ context->get_lifetime_resolver ().get_num_bound_regions ()));
context->insert_type (function.get_mappings (), fnType);
result = fnType;
void
TypeCheckImplItem::visit (HIR::TypeAlias &alias)
{
+ auto binder_pin = context->push_lifetime_binder ();
+
+ if (alias.has_generics ())
+ resolve_generic_params (alias.get_generic_params (), substitutions);
+
TyTy::BaseType *actual_type
= TypeCheckType::Resolve (alias.get_type_aliased ().get ());
TyTy::BaseType *self;
std::vector<TyTy::SubstitutionParamMapping> substitutions;
- TyTy::BaseType *result;
+ TyTy::BaseType *result = nullptr;
};
class TypeCheckImplItemWithTrait : public TypeCheckBase,
}
// create argument mappings
- *infer_arguments
- = TyTy::SubstitutionArgumentMappings (std::move (args), {}, locus);
+ *infer_arguments = TyTy::SubstitutionArgumentMappings (
+ std::move (args), {},
+ TyTy::SubstitutionArgumentMappings::regions_from_nullable_args (
+ infer_arguments),
+ locus);
TyTy::BaseType *infer = SubstMapperInternal::Resolve (self, *infer_arguments);
for (auto &where_clause_item : alias.get_where_clause ().get_items ())
{
- ResolveWhereClauseItem::Resolve (*where_clause_item.get ());
+ ResolveWhereClauseItem::Resolve (*where_clause_item);
}
infered = actual_type;
}
void
TypeCheckItem::visit (HIR::TupleStruct &struct_decl)
{
+ auto lifetime_pin = context->push_clean_lifetime_resolver ();
+
std::vector<TyTy::SubstitutionParamMapping> substitutions;
if (struct_decl.has_generics ())
resolve_generic_params (struct_decl.get_generic_params (), substitutions);
for (auto &where_clause_item : struct_decl.get_where_clause ().get_items ())
{
- ResolveWhereClauseItem::Resolve (*where_clause_item.get ());
+ ResolveWhereClauseItem::Resolve (*where_clause_item);
}
std::vector<TyTy::StructFieldType *> fields;
{
TyTy::BaseType *field_type
= TypeCheckType::Resolve (field.get_field_type ().get ());
- TyTy::StructFieldType *ty_field
+ auto *ty_field
= new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
std::to_string (idx), field_type,
field.get_locus ());
TyTy::ADTType::ReprOptions repr
= parse_repr_options (attrs, struct_decl.get_locus ());
- TyTy::BaseType *type
- = new TyTy::ADTType (struct_decl.get_mappings ().get_hirid (),
- mappings->get_next_hir_id (),
- struct_decl.get_identifier ().as_string (), ident,
- TyTy::ADTType::ADTKind::TUPLE_STRUCT,
- std::move (variants), std::move (substitutions), repr);
+ TyTy::BaseType *type = new TyTy::ADTType (
+ struct_decl.get_mappings ().get_hirid (), mappings->get_next_hir_id (),
+ struct_decl.get_identifier ().as_string (), ident,
+ TyTy::ADTType::ADTKind::TUPLE_STRUCT, std::move (variants),
+ std::move (substitutions), repr,
+ TyTy::SubstitutionArgumentMappings::empty (
+ context->get_lifetime_resolver ().get_num_bound_regions ()));
context->insert_type (struct_decl.get_mappings (), type);
infered = type;
void
TypeCheckItem::visit (HIR::StructStruct &struct_decl)
{
+ auto lifetime_pin = context->push_clean_lifetime_resolver ();
+
std::vector<TyTy::SubstitutionParamMapping> substitutions;
if (struct_decl.has_generics ())
resolve_generic_params (struct_decl.get_generic_params (), substitutions);
for (auto &where_clause_item : struct_decl.get_where_clause ().get_items ())
{
- ResolveWhereClauseItem::Resolve (*where_clause_item.get ());
+ ResolveWhereClauseItem::Resolve (*where_clause_item);
}
std::vector<TyTy::StructFieldType *> fields;
{
TyTy::BaseType *field_type
= TypeCheckType::Resolve (field.get_field_type ().get ());
- TyTy::StructFieldType *ty_field
+ auto *ty_field
= new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
field.get_field_name ().as_string (),
field_type, field.get_locus ());
TyTy::ADTType::ReprOptions repr
= parse_repr_options (attrs, struct_decl.get_locus ());
- TyTy::BaseType *type
- = new TyTy::ADTType (struct_decl.get_mappings ().get_hirid (),
- mappings->get_next_hir_id (),
- struct_decl.get_identifier ().as_string (), ident,
- TyTy::ADTType::ADTKind::STRUCT_STRUCT,
- std::move (variants), std::move (substitutions), repr);
+ TyTy::BaseType *type = new TyTy::ADTType (
+ struct_decl.get_mappings ().get_hirid (), mappings->get_next_hir_id (),
+ struct_decl.get_identifier ().as_string (), ident,
+ TyTy::ADTType::ADTKind::STRUCT_STRUCT, std::move (variants),
+ std::move (substitutions), repr,
+ TyTy::SubstitutionArgumentMappings::empty (
+ context->get_lifetime_resolver ().get_num_bound_regions ()));
context->insert_type (struct_decl.get_mappings (), type);
infered = type;
void
TypeCheckItem::visit (HIR::Enum &enum_decl)
{
+ auto lifetime_pin = context->push_clean_lifetime_resolver ();
std::vector<TyTy::SubstitutionParamMapping> substitutions;
if (enum_decl.has_generics ())
resolve_generic_params (enum_decl.get_generic_params (), substitutions);
void
TypeCheckItem::visit (HIR::Union &union_decl)
{
+ auto lifetime_pin = context->push_clean_lifetime_resolver ();
std::vector<TyTy::SubstitutionParamMapping> substitutions;
if (union_decl.has_generics ())
resolve_generic_params (union_decl.get_generic_params (), substitutions);
for (auto &where_clause_item : union_decl.get_where_clause ().get_items ())
{
- ResolveWhereClauseItem::Resolve (*where_clause_item.get ());
+ ResolveWhereClauseItem::Resolve (*where_clause_item);
}
std::vector<TyTy::StructFieldType *> fields;
{
TyTy::BaseType *variant_type
= TypeCheckType::Resolve (variant.get_field_type ().get ());
- TyTy::StructFieldType *ty_variant
+ auto *ty_variant
= new TyTy::StructFieldType (variant.get_mappings ().get_hirid (),
variant.get_field_name ().as_string (),
variant_type, variant.get_locus ());
void
TypeCheckItem::visit (HIR::ImplBlock &impl_block)
{
+ auto binder_pin = context->push_clean_lifetime_resolver (true);
+
bool failed_flag = false;
std::vector<TyTy::SubstitutionParamMapping> substitutions
= resolve_impl_block_substitutions (impl_block, failed_flag);
void
TypeCheckItem::visit (HIR::Function &function)
{
+ auto lifetime_pin = context->push_clean_lifetime_resolver ();
std::vector<TyTy::SubstitutionParamMapping> substitutions;
if (function.has_generics ())
resolve_generic_params (function.get_generic_params (), substitutions);
for (auto &where_clause_item : function.get_where_clause ().get_items ())
{
- ResolveWhereClauseItem::Resolve (*where_clause_item.get ());
+ ResolveWhereClauseItem::Resolve (*where_clause_item);
}
TyTy::BaseType *ret_type = nullptr;
{
// get the name as well required for later on
auto param_tyty = TypeCheckType::Resolve (param.get_type ().get ());
- params.push_back (std::pair<HIR::Pattern *, TyTy::BaseType *> (
- param.get_param_name ().get (), param_tyty));
+ params.emplace_back (param.get_param_name ().get (), param_tyty);
context->insert_type (param.get_mappings (), param_tyty);
TypeCheckPattern::Resolve (param.get_param_name ().get (), param_tyty);
rust_assert (ok);
RustIdent ident{*canonical_path, function.get_locus ()};
- auto fnType = new TyTy::FnType (function.get_mappings ().get_hirid (),
- function.get_mappings ().get_defid (),
- function.get_function_name ().as_string (),
- ident, TyTy::FnType::FNTYPE_DEFAULT_FLAGS,
- ABI::RUST, std::move (params), ret_type,
- std::move (substitutions));
- context->insert_type (function.get_mappings (), fnType);
+ auto fn_type = new TyTy::FnType (
+ function.get_mappings ().get_hirid (),
+ function.get_mappings ().get_defid (),
+ function.get_function_name ().as_string (), ident,
+ TyTy::FnType::FNTYPE_DEFAULT_FLAGS, ABI::RUST, std::move (params), ret_type,
+ std::move (substitutions),
+ TyTy::SubstitutionArgumentMappings::empty (
+ context->get_lifetime_resolver ().get_num_bound_regions ()));
+
+ context->insert_type (function.get_mappings (), fn_type);
// need to get the return type from this
- TyTy::FnType *resolved_fn_type = fnType;
+ TyTy::FnType *resolved_fn_type = fn_type;
auto expected_ret_tyty = resolved_fn_type->get_return_type ();
context->push_return_type (TypeCheckContextItem (&function),
expected_ret_tyty);
+ context->switch_to_fn_body ();
auto block_expr_ty
= TypeCheckExpr::Resolve (function.get_definition ().get ());
context->pop_return_type ();
- infered = fnType;
+ infered = fn_type;
}
void
TypeCheckItem::visit (HIR::Module &module)
{
for (auto &item : module.get_items ())
- TypeCheckItem::Resolve (*item.get ());
+ TypeCheckItem::Resolve (*item);
}
void
for (auto &where_clause_item : impl_block.get_where_clause ().get_items ())
{
- ResolveWhereClauseItem::Resolve (*where_clause_item.get ());
+ ResolveWhereClauseItem::Resolve (*where_clause_item);
}
auto specified_bound = TyTy::TypeBoundPredicate::error ();
if (impl_block.has_trait_ref ())
{
std::unique_ptr<HIR::TypePath> &ref = impl_block.get_trait_ref ();
- trait_reference = TraitResolver::Resolve (*ref.get ());
+ trait_reference = TraitResolver::Resolve (*ref);
rust_assert (!trait_reference->is_error ());
// we don't error out here see: gcc/testsuite/rust/compile/traits2.rs
// for example
specified_bound
- = get_predicate_from_bound (*ref.get (), impl_block.get_type ().get ());
+ = get_predicate_from_bound (*ref, impl_block.get_type ().get ());
}
TyTy::BaseType *self = TypeCheckType::Resolve (impl_block.get_type ().get ());
if (impl_block.has_trait_ref ())
{
std::unique_ptr<HIR::TypePath> &ref = impl_block.get_trait_ref ();
- trait_reference = TraitResolver::Resolve (*ref.get ());
+ trait_reference = TraitResolver::Resolve (*ref);
rust_assert (!trait_reference->is_error ());
// we don't error out here see: gcc/testsuite/rust/compile/traits2.rs
// for example
specified_bound
- = get_predicate_from_bound (*ref.get (), impl_block.get_type ().get ());
+ = get_predicate_from_bound (*ref, impl_block.get_type ().get ());
}
bool is_trait_impl_block = !trait_reference->is_error ();
std::string trait_item_name = trait_item_ref.get_identifier ();
std::string impl_item_name
= implemented_trait_item->get_identifier ();
- found = trait_item_name.compare (impl_item_name) == 0;
+ found = trait_item_name == impl_item_name;
if (found)
break;
}
bool is_required_trait_item = !trait_item_ref.is_optional ();
if (!found && is_required_trait_item)
- missing_trait_items.push_back (trait_item_ref);
+ missing_trait_items.emplace_back (trait_item_ref);
}
- if (missing_trait_items.size () > 0)
+ if (!missing_trait_items.empty ())
{
std::string missing_items_buf;
rich_location r (line_table, impl_block.get_locus ());
infered = new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
return;
}
+ std::vector<TyTy::Region> regions;
+
infered = SubstMapper::Resolve (infered, expr.get_locus (),
- &item_seg.get_generic_args ());
+ &item_seg.get_generic_args (),
+ context->regions_from_generic_args (
+ item_seg.get_generic_args ()));
}
// continue on as a path-in-expression
if (seg.has_generic_args ())
{
lookup = SubstMapper::Resolve (lookup, expr.get_locus (),
- &seg.get_generic_args ());
+ &seg.get_generic_args (),
+ context->regions_from_generic_args (
+ seg.get_generic_args ()));
if (lookup->get_kind () == TyTy::TypeKind::ERROR)
return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
}
if (seg.has_generic_args ())
{
- tyseg = SubstMapper::Resolve (tyseg, expr_locus,
- &seg.get_generic_args ());
+ tyseg
+ = SubstMapper::Resolve (tyseg, expr_locus, &seg.get_generic_args (),
+ context->regions_from_generic_args (
+ seg.get_generic_args ()));
if (tyseg->get_kind () == TyTy::TypeKind::ERROR)
return;
}
void
TypeCheckType::visit (HIR::BareFunctionType &fntype)
{
+ auto binder_pin = context->push_lifetime_binder ();
+ for (auto &lifetime_param : fntype.get_for_lifetimes ())
+ {
+ context->intern_and_insert_lifetime (lifetime_param.get_lifetime ());
+ }
+
TyTy::BaseType *return_type;
if (fntype.has_return_type ())
{
= new TyTy::ErrorType (path.get_mappings ().get_hirid ());
return;
}
- translated = SubstMapper::Resolve (translated, path.get_locus (),
- &generic_seg.get_generic_args ());
+ translated
+ = SubstMapper::Resolve (translated, path.get_locus (),
+ &generic_seg.get_generic_args (),
+ context->regions_from_generic_args (
+ generic_seg.get_generic_args ()));
}
}
HIR::TypePathSegmentGeneric *generic_segment
= static_cast<HIR::TypePathSegmentGeneric *> (seg.get ());
+ auto regions = context->regions_from_generic_args (
+ generic_segment->get_generic_args ());
lookup = SubstMapper::Resolve (lookup, path.get_locus (),
- &generic_segment->get_generic_args ());
+ &generic_segment->get_generic_args (),
+ regions);
if (lookup->get_kind () == TyTy::TypeKind::ERROR)
return new TyTy::ErrorType (seg->get_mappings ().get_hirid ());
}
{
HIR::GenericArgs empty
= HIR::GenericArgs::create_empty (path.get_locus ());
- lookup = SubstMapper::Resolve (lookup, path.get_locus (), &empty);
+ lookup
+ = SubstMapper::Resolve (lookup, path.get_locus (), &empty,
+ context->regions_from_generic_args (empty));
}
*root_resolved_node_id = ref_node_id;
if (seg->is_generic_segment ())
{
- HIR::TypePathSegmentGeneric *generic_segment
+ auto *generic_segment
= static_cast<HIR::TypePathSegmentGeneric *> (seg.get ());
+ std::vector<TyTy::Region> regions;
+ for (auto &lifetime :
+ generic_segment->get_generic_args ().get_lifetime_args ())
+ {
+ auto region = context->lookup_and_resolve_lifetime (lifetime);
+ if (!region.has_value ())
+ {
+ rust_error_at (lifetime.get_locus (),
+ "failed to resolve lifetime");
+ return new TyTy::ErrorType (expr_id);
+ }
+ regions.push_back (region.value ());
+ }
+
tyseg = SubstMapper::Resolve (tyseg, expr_locus,
- &generic_segment->get_generic_args ());
+ &generic_segment->get_generic_args (),
+ regions);
if (tyseg->get_kind () == TyTy::TypeKind::ERROR)
return new TyTy::ErrorType (expr_id);
}
HIR::TypeParamBound &b = *bound.get ();
HIR::TraitBound &trait_bound = static_cast<HIR::TraitBound &> (b);
+ auto binder_pin = context->push_lifetime_binder ();
+ for (auto &lifetime_param : trait_bound.get_for_lifetimes ())
+ {
+ context->intern_and_insert_lifetime (lifetime_param.get_lifetime ());
+ }
+
TyTy::TypeBoundPredicate predicate = get_predicate_from_bound (
trait_bound.get_path (),
nullptr /*this will setup a PLACEHOLDER for self*/);
TypeCheckType::visit (HIR::ReferenceType &type)
{
TyTy::BaseType *base = TypeCheckType::Resolve (type.get_base_type ().get ());
- translated
- = new TyTy::ReferenceType (type.get_mappings ().get_hirid (),
- TyTy::TyVar (base->get_ref ()), type.get_mut ());
-}
+ rust_assert (type.has_lifetime ());
+ auto region = context->lookup_and_resolve_lifetime (type.get_lifetime ());
+ if (!region.has_value ())
+ {
+ rust_error_at (type.get_locus (), "failed to resolve lifetime");
+ translated = new TyTy::ErrorType (type.get_mappings ().get_hirid ());
+ return;
+ }
+ translated = new TyTy::ReferenceType (type.get_mappings ().get_hirid (),
+ TyTy::TyVar (base->get_ref ()),
+ type.get_mut (), region.value ());
+} // namespace Resolver
void
TypeCheckType::visit (HIR::RawPointerType &type)
ResolveWhereClauseItem::Resolve (HIR::WhereClauseItem &item)
{
ResolveWhereClauseItem resolver;
+
+ auto binder_pin = resolver.context->push_lifetime_binder ();
+
switch (item.get_item_type ())
{
case HIR::WhereClauseItem::LIFETIME:
void
ResolveWhereClauseItem::visit (HIR::LifetimeWhereClauseItem &item)
-{}
+{
+ auto lhs = context->lookup_and_resolve_lifetime (item.get_lifetime ());
+ if (!lhs.has_value ())
+ {
+ rust_error_at (UNKNOWN_LOCATION, "failed to resolve lifetime");
+ }
+ for (auto &lifetime : item.get_lifetime_bounds ())
+ {
+ auto rhs_i = context->lookup_and_resolve_lifetime (lifetime);
+ if (!rhs_i.has_value ())
+ {
+ rust_error_at (UNKNOWN_LOCATION, "failed to resolve lifetime");
+ }
+ }
+}
void
ResolveWhereClauseItem::visit (HIR::TypeBoundWhereClauseItem &item)
{
+ auto binder_pin = context->push_lifetime_binder ();
+ if (item.has_for_lifetimes ())
+ {
+ for (auto &lifetime_param : item.get_for_lifetimes ())
+ {
+ context->intern_and_insert_lifetime (lifetime_param.get_lifetime ());
+ }
+ }
+
auto &binding_type_path = item.get_bound_type ();
TyTy::BaseType *binding = TypeCheckType::Resolve (binding_type_path.get ());
switch (bound->get_bound_type ())
{
case HIR::TypeParamBound::BoundType::TRAITBOUND: {
- HIR::TraitBound *b = static_cast<HIR::TraitBound *> (bound.get ());
+ auto *b = static_cast<HIR::TraitBound *> (bound.get ());
TyTy::TypeBoundPredicate predicate
= get_predicate_from_bound (b->get_path (),
specified_bounds.push_back (std::move (predicate));
}
break;
+ case HIR::TypeParamBound::BoundType::LIFETIME: {
+ if (binding->is<TyTy::ParamType> ())
+ {
+ auto *b = static_cast<HIR::Lifetime *> (bound.get ());
+ auto region = context->lookup_and_resolve_lifetime (*b);
+ if (!region.has_value ())
+ {
+ rust_error_at (UNKNOWN_LOCATION,
+ "failed to resolve lifetime");
+ }
+ }
+ }
+ break;
default:
break;
namespace Rust {
namespace Resolver {
+tl::optional<TyTy::Region>
+TypeCheckContext::LifetimeResolver::resolve (const Lifetime &placeholder) const
+{
+ if (placeholder.is_static ())
+ return TyTy::Region::make_static ();
+
+ if (placeholder == Lifetime::anonymous_lifetime ())
+ return TyTy::Region::make_anonymous ();
+
+ for (auto it = lifetime_lookup.rbegin (); it != lifetime_lookup.rend (); ++it)
+ {
+ if (it->first == placeholder)
+ {
+ if (it->second.scope <= ITEM_SCOPE)
+ {
+ // It is useful to have the static lifetime and named
+ // lifetimed disjoint so we add the +1 here.
+ return (is_body)
+ ? TyTy::Region::make_named (it->second.index + 1)
+ : TyTy::Region::make_early_bound (it->second.index);
+ }
+ else
+ {
+ return TyTy::Region::make_late_bound (get_current_scope ()
+ - it->second.scope,
+ it->second.index);
+ }
+ }
+ }
+
+ return tl::nullopt;
+}
+
void
TypeResolution::Resolve (HIR::Crate &crate)
{
TyTy::BaseType *
TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
{
+ auto binder_pin = context->push_clean_lifetime_resolver ();
+
std::vector<TyTy::SubstitutionParamMapping> substitutions
= inherited_substitutions;
{
switch (generic_param.get ()->get_kind ())
{
- case HIR::GenericParam::GenericKind::LIFETIME:
+ case HIR::GenericParam::GenericKind::LIFETIME: {
+ auto lifetime_param
+ = static_cast<HIR::LifetimeParam &> (*generic_param);
+
+ context->intern_and_insert_lifetime (
+ lifetime_param.get_lifetime ());
+ // TODO: Handle lifetime bounds
+ }
+ break;
case HIR::GenericParam::GenericKind::CONST:
// FIXME: Skipping Lifetime and Const completely until better
// handling.
break;
case HIR::SelfParam::IMM_REF:
- self_type = new TyTy::ReferenceType (
- self_param.get_mappings ().get_hirid (),
- TyTy::TyVar (self->get_ref ()), Mutability::Imm);
- break;
-
- case HIR::SelfParam::MUT_REF:
- self_type = new TyTy::ReferenceType (
- self_param.get_mappings ().get_hirid (),
- TyTy::TyVar (self->get_ref ()), Mutability::Mut);
+ case HIR::SelfParam::MUT_REF: {
+ auto mutability
+ = self_param.get_self_kind () == HIR::SelfParam::IMM_REF
+ ? Mutability::Imm
+ : Mutability::Mut;
+ rust_assert (self_param.has_lifetime ());
+
+ auto maybe_region = context->lookup_and_resolve_lifetime (
+ self_param.get_lifetime ());
+
+ if (!maybe_region.has_value ())
+ {
+ rust_error_at (self_param.get_locus (),
+ "failed to resolve lifetime");
+ return get_error ();
+ }
+ self_type = new TyTy::ReferenceType (
+ self_param.get_mappings ().get_hirid (),
+ TyTy::TyVar (self->get_ref ()), mutability,
+ maybe_region.value ());
+ }
break;
default:
rust_assert (ok);
RustIdent ident{*canonical_path, fn.get_locus ()};
- auto resolved
- = new TyTy::FnType (fn.get_mappings ().get_hirid (),
- fn.get_mappings ().get_defid (),
- function.get_function_name ().as_string (), ident,
- function.is_method ()
- ? TyTy::FnType::FNTYPE_IS_METHOD_FLAG
+ auto resolved = new TyTy::FnType (
+ fn.get_mappings ().get_hirid (), fn.get_mappings ().get_defid (),
+ function.get_function_name ().as_string (), ident,
+ function.is_method () ? TyTy::FnType::FNTYPE_IS_METHOD_FLAG
: TyTy::FnType::FNTYPE_DEFAULT_FLAGS,
- ABI::RUST, std::move (params), ret_type, substitutions);
-
+ ABI::RUST, std::move (params), ret_type, substitutions,
+ TyTy::SubstitutionArgumentMappings::empty (
+ context->get_lifetime_resolver ().get_num_bound_regions ()));
context->insert_type (fn.get_mappings (), resolved);
return resolved;
}
#include "rust-tyty.h"
#include "rust-hir-trait-reference.h"
#include "rust-autoderef.h"
+#include "rust-tyty-region.h"
#include <stack>
WARN_UNUSED_RESULT tl::optional<Lifetime>
lookup_lifetime (const HIR::Lifetime &lifetime) const;
+ WARN_UNUSED_RESULT tl::optional<TyTy::Region>
+ lookup_and_resolve_lifetime (const HIR::Lifetime &lifetime) const;
+
void intern_and_insert_lifetime (const HIR::Lifetime &lifetime);
+ WARN_UNUSED_RESULT std::vector<TyTy::Region>
+ regions_from_generic_args (const HIR::GenericArgs &args) const;
+
private:
TypeCheckContext ();
{placeholder, {get_current_scope (), binder_size_stack.top ()++}});
}
+ WARN_UNUSED_RESULT tl::optional<TyTy::Region>
+ resolve (const Lifetime &placeholder) const;
+
/** Only to be used by the guard. */
void push_binder () { binder_size_stack.push (0); }
/** Only to be used by the guard. */
namespace Resolver {
SubstMapper::SubstMapper (HirId ref, HIR::GenericArgs *generics,
+ const std::vector<TyTy::Region> ®ions,
location_t locus)
- : resolved (new TyTy::ErrorType (ref)), generics (generics), locus (locus)
+ : resolved (new TyTy::ErrorType (ref)), generics (generics),
+ regions (regions), locus (locus)
{}
TyTy::BaseType *
SubstMapper::Resolve (TyTy::BaseType *base, location_t locus,
- HIR::GenericArgs *generics)
+ HIR::GenericArgs *generics,
+ const std::vector<TyTy::Region> ®ions)
{
- SubstMapper mapper (base->get_ref (), generics, locus);
+ SubstMapper mapper (base->get_ref (), generics, regions, locus);
base->accept_vis (mapper);
rust_assert (mapper.resolved != nullptr);
return mapper.resolved;
TyTy::BaseType *
SubstMapper::InferSubst (TyTy::BaseType *base, location_t locus)
{
- return SubstMapper::Resolve (base, locus, nullptr);
+ return SubstMapper::Resolve (base, locus, nullptr, {});
}
bool
else
{
TyTy::SubstitutionArgumentMappings mappings
- = type.get_mappings_from_generic_args (*generics);
+ = type.get_mappings_from_generic_args (*generics, regions);
if (mappings.is_error ())
return;
else
{
TyTy::SubstitutionArgumentMappings mappings
- = type.get_mappings_from_generic_args (*generics);
+ = type.get_mappings_from_generic_args (*generics, regions);
if (mappings.is_error ())
return;
SubstMapper::visit (TyTy::PlaceholderType &type)
{
rust_assert (type.can_resolve ());
- resolved = SubstMapper::Resolve (type.resolve (), locus, generics);
+ resolved = SubstMapper::Resolve (type.resolve (), locus, generics, regions);
}
void
else
{
TyTy::SubstitutionArgumentMappings mappings
- = type.get_mappings_from_generic_args (*generics);
+ = type.get_mappings_from_generic_args (*generics, regions);
if (mappings.is_error ())
return;
{
public:
static TyTy::BaseType *Resolve (TyTy::BaseType *base, location_t locus,
- HIR::GenericArgs *generics = nullptr);
+ HIR::GenericArgs *generics = nullptr,
+ const std::vector<TyTy::Region> ®ions
+ = {});
static TyTy::BaseType *InferSubst (TyTy::BaseType *base, location_t locus);
void visit (TyTy::ClosureType &) override { rust_unreachable (); }
private:
- SubstMapper (HirId ref, HIR::GenericArgs *generics, location_t locus);
+ SubstMapper (HirId ref, HIR::GenericArgs *generics,
+ const std::vector<TyTy::Region> ®ions, location_t locus);
TyTy::BaseType *resolved;
HIR::GenericArgs *generics;
+ const std::vector<TyTy::Region> ®ions;
location_t locus;
};
rust_unreachable ();
}
+WARN_UNUSED_RESULT tl::optional<TyTy::Region>
+TypeCheckContext::lookup_and_resolve_lifetime (
+ const HIR::Lifetime &lifetime) const
+{
+ auto maybe_interned = lookup_lifetime (lifetime);
+ if (!maybe_interned)
+ return tl::nullopt;
+
+ return get_lifetime_resolver ().resolve (maybe_interned.value ());
+}
void
TypeCheckContext::intern_and_insert_lifetime (const HIR::Lifetime &lifetime)
{
get_lifetime_resolver ().insert_mapping (intern_lifetime (lifetime));
}
+WARN_UNUSED_RESULT std::vector<TyTy::Region>
+TypeCheckContext::regions_from_generic_args (const HIR::GenericArgs &args) const
+{
+ std::vector<TyTy::Region> regions;
+ for (const auto &lifetime : args.get_lifetime_args ())
+ {
+ auto resolved = lookup_and_resolve_lifetime (lifetime);
+ if (!resolved)
+ {
+ rust_error_at (lifetime.get_locus (), "unresolved lifetime");
+ return {};
+ }
+ regions.push_back (*resolved);
+ }
+ return regions;
+}
+
// TypeCheckContextItem
TypeCheckContextItem::Item::Item (HIR::Function *item) : item (item) {}
used_arguments
= SubstitutionArgumentMappings (copied_arg_mappings, {},
+ other.used_arguments.get_regions (),
other.used_arguments.get_locus ());
}
used_arguments
= SubstitutionArgumentMappings (copied_arg_mappings, {},
+ other.used_arguments.get_regions (),
other.used_arguments.get_locus ());
return *this;
}
// now actually perform a substitution
- used_arguments = get_mappings_from_generic_args (*generic_args);
+ used_arguments = get_mappings_from_generic_args (
+ *generic_args,
+ Resolver::TypeCheckContext::get ()->regions_from_generic_args (
+ *generic_args));
error_flag |= used_arguments.is_error ();
auto &subst_mappings = used_arguments;
}
SubstitutionArgumentMappings adjusted (adjusted_mappings, {},
+ gargs.get_regions (),
gargs.get_locus (),
gargs.get_subst_cb (),
true /* trait-mode-flag */);
// <http://www.gnu.org/licenses/>.
#include "rust-tyty-subst.h"
+
+#include <utility>
#include "rust-tyty.h"
#include "rust-hir-type-check.h"
#include "rust-substitution-mapper.h"
+ (argument != nullptr ? ":" + argument->as_string () : "");
}
+const RegionParamList &
+SubstitutionArgumentMappings::get_regions () const
+{
+ return regions;
+}
+
+RegionParamList &
+SubstitutionArgumentMappings::get_mut_regions ()
+{
+ return regions;
+}
+
// SubstitutionArgumentMappings
SubstitutionArgumentMappings::SubstitutionArgumentMappings (
std::vector<SubstitutionArg> mappings,
- std::map<std::string, BaseType *> binding_args, location_t locus,
- ParamSubstCb param_subst_cb, bool trait_item_flag, bool error_flag)
- : mappings (mappings), binding_args (binding_args), locus (locus),
- param_subst_cb (param_subst_cb), trait_item_flag (trait_item_flag),
- error_flag (error_flag)
+ std::map<std::string, BaseType *> binding_args, RegionParamList regions,
+ location_t locus, ParamSubstCb param_subst_cb, bool trait_item_flag,
+ bool error_flag)
+ : mappings (std::move (mappings)), binding_args (binding_args),
+ regions (regions), locus (locus), param_subst_cb (param_subst_cb),
+ trait_item_flag (trait_item_flag), error_flag (error_flag)
{}
SubstitutionArgumentMappings::SubstitutionArgumentMappings (
const SubstitutionArgumentMappings &other)
: mappings (other.mappings), binding_args (other.binding_args),
- locus (other.locus), param_subst_cb (nullptr),
+ regions (other.regions), locus (other.locus), param_subst_cb (nullptr),
trait_item_flag (other.trait_item_flag), error_flag (other.error_flag)
{}
{
mappings = other.mappings;
binding_args = other.binding_args;
+ regions = other.regions;
locus = other.locus;
param_subst_cb = nullptr;
trait_item_flag = other.trait_item_flag;
SubstitutionArgumentMappings
SubstitutionArgumentMappings::error ()
{
- return SubstitutionArgumentMappings ({}, {}, UNDEF_LOCATION, nullptr, false,
- true);
+ return SubstitutionArgumentMappings ({}, {}, 0, UNDEF_LOCATION, nullptr,
+ false, true);
}
SubstitutionArgumentMappings
-SubstitutionArgumentMappings::empty ()
+SubstitutionArgumentMappings::empty (size_t num_regions)
{
- return SubstitutionArgumentMappings ({}, {}, UNDEF_LOCATION, nullptr, false,
- false);
+ return SubstitutionArgumentMappings ({}, {}, num_regions, UNDEF_LOCATION,
+ nullptr, false, false);
}
bool
bool
SubstitutionArgumentMappings::get_argument_for_symbol (
- const ParamType *param_to_find, SubstitutionArg *argument)
+ const ParamType *param_to_find, SubstitutionArg *argument) const
{
- for (auto &mapping : mappings)
+ for (const auto &mapping : mappings)
{
const ParamType *p = mapping.get_param_ty ();
- if (p->get_symbol ().compare (param_to_find->get_symbol ()) == 0)
+ if (p->get_symbol () == param_to_find->get_symbol ())
{
*argument = mapping;
return true;
}
return false;
}
+tl::optional<size_t>
+SubstitutionArgumentMappings::find_symbol (const ParamType ¶m_to_find) const
+{
+ auto it = std::find_if (mappings.begin (), mappings.end (),
+ [param_to_find] (const SubstitutionArg &arg) {
+ return arg.get_param_ty ()->get_symbol ()
+ == param_to_find.get_symbol ();
+ });
+ if (it == mappings.end ())
+ return tl::nullopt;
+ return std::distance (mappings.begin (), it);
+}
bool
SubstitutionArgumentMappings::get_argument_at (size_t index,
{
return substitutions.size ();
}
+size_t
+SubstitutionRef::get_num_lifetime_params () const
+{
+ return used_arguments.get_regions ().size ();
+}
+size_t
+SubstitutionRef::get_num_type_params () const
+{
+ return get_num_substitutions ();
+}
std::vector<SubstitutionParamMapping> &
SubstitutionRef::get_substs ()
bool
SubstitutionRef::needs_substitution () const
{
- for (auto &sub : substitutions)
- {
- if (sub.need_substitution ())
- return true;
- }
- return false;
+ return std::any_of (substitutions.begin (), substitutions.end (),
+ std::mem_fn (
+ &SubstitutionParamMapping::needs_substitution));
}
bool
return n;
}
-SubstitutionArgumentMappings
+const SubstitutionArgumentMappings &
SubstitutionRef::get_used_arguments () const
{
return used_arguments;
}
SubstitutionArgumentMappings
-SubstitutionRef::get_mappings_from_generic_args (HIR::GenericArgs &args)
+SubstitutionRef::get_mappings_from_generic_args (
+ HIR::GenericArgs &args, const std::vector<Region> ®ions)
{
std::map<std::string, BaseType *> binding_arguments;
if (args.get_binding_args ().size () > 0)
// this resolved default might already contain default parameters
if (!resolved->is_concrete ())
{
- SubstitutionArgumentMappings intermediate (mappings,
- binding_arguments,
- args.get_locus ());
+ SubstitutionArgumentMappings intermediate (
+ mappings, binding_arguments,
+ {used_arguments.get_regions ().size ()}, args.get_locus ());
resolved = Resolver::SubstMapperInternal::Resolve (resolved,
intermediate);
}
}
- return SubstitutionArgumentMappings (mappings, binding_arguments,
- args.get_locus ());
+ return {mappings, binding_arguments,
+ RegionParamList::from_subst (used_arguments.get_regions ().size (),
+ regions),
+ args.get_locus ()};
}
BaseType *
SubstitutionArgumentMappings infer_arguments (std::move (args),
{} /* binding_arguments */,
+ used_arguments.get_regions (),
locus);
return handle_substitions (infer_arguments);
}
return SubstitutionArgumentMappings (resolved_mappings,
mappings.get_binding_args (),
+ mappings.get_regions (),
mappings.get_locus (),
mappings.get_subst_cb (),
mappings.trait_item_mode ());
return SubstitutionArgumentMappings (resolved_mappings,
mappings.get_binding_args (),
+ mappings.get_regions (),
mappings.get_locus ());
}
#include "rust-location.h"
#include "rust-hir-full-decls.h"
#include "rust-tyty-bounds.h"
+#include "rust-tyty-region.h"
+
+#include <optional.h>
namespace Rust {
namespace TyTy {
ParamType *param;
};
+/**
+ * Represents the part of the parameter list that contains lifetime
+ * parameters.
+ *
+ * ```
+ * Foo<'a, 'b, i32, 8>
+ * ^^^^^^
+ * ```
+ *
+ * It has fixed size based on the number of lifetime parameters and they are
+ * indexed based on their order.
+ *
+ * All regions are initially set to unresolved. When type instantiation is
+ * encountered, all explicitly mentioned lifetimes are resolved to bound
+ * lifetimes. The remaining unresolved lifetimes are set to anonymous. During
+ * BIR construction, all lifetimes are replaced with free region variables.
+ * Inference of anonymous regions happens automatically using BIR subtyping
+ * pass.
+ */
+class RegionParamList
+{
+ std::vector<Region> regions;
+
+public:
+ RegionParamList (size_t num_regions) : regions (num_regions) {}
+
+ Region *begin () { return regions.data (); }
+ Region *end () { return regions.data () + regions.size (); }
+ Region &operator[] (size_t index) { return regions.at (index); }
+ const Region &operator[] (size_t index) const { return regions.at (index); }
+ WARN_UNUSED_RESULT const Region *begin () const { return regions.data (); }
+ WARN_UNUSED_RESULT const Region *end () const
+ {
+ return regions.data () + regions.size ();
+ }
+ size_t size () const { return regions.size (); }
+
+ /**
+ * Takes regions from the `subst` parameter and fills the rest with anonymous
+ * regions.
+ */
+ static RegionParamList from_subst (size_t num_regions,
+ std::vector<Region> subst)
+ {
+ RegionParamList list (num_regions);
+ for (size_t i = 0; i < subst.size (); i++)
+ list.regions.at (i) = subst.at (i);
+ for (size_t i = subst.size (); i < num_regions; i++)
+ {
+ list.regions.at (i) = Region::make_anonymous ();
+ }
+ return list;
+ }
+};
+
class SubstitutionArg
{
public:
public:
SubstitutionArgumentMappings (std::vector<SubstitutionArg> mappings,
std::map<std::string, BaseType *> binding_args,
- location_t locus,
+ RegionParamList regions, location_t locus,
ParamSubstCb param_subst_cb = nullptr,
bool trait_item_flag = false,
bool error_flag = false);
= default;
static SubstitutionArgumentMappings error ();
- static SubstitutionArgumentMappings empty ();
+
+ /** Creates empty substitution argument mappings with unresolved regions */
+ static SubstitutionArgumentMappings empty (size_t num_regions = 0);
+
+ static RegionParamList
+ regions_from_nullable_args (SubstitutionArgumentMappings *args)
+ {
+ if (args == nullptr)
+ return RegionParamList (0);
+
+ return args->get_regions ();
+ }
bool is_error () const;
bool get_argument_for_symbol (const ParamType *param_to_find,
- SubstitutionArg *argument);
+ SubstitutionArg *argument) const;
+
+ /** Return type parameter index for symbol */
+ tl::optional<size_t> find_symbol (const ParamType ¶m_to_find) const;
bool get_argument_at (size_t index, SubstitutionArg *argument);
const std::map<std::string, BaseType *> &get_binding_args () const;
+ const RegionParamList &get_regions () const;
+ RegionParamList &get_mut_regions ();
+
std::string as_string () const;
void on_param_subst (const ParamType &p, const SubstitutionArg &a) const;
private:
std::vector<SubstitutionArg> mappings;
std::map<std::string, BaseType *> binding_args;
+ RegionParamList regions;
location_t locus;
ParamSubstCb param_subst_cb;
bool trait_item_flag;
size_t get_num_substitutions () const;
+ size_t get_num_lifetime_params () const;
+
+ size_t get_num_type_params () const;
+
std::vector<SubstitutionParamMapping> &get_substs ();
const std::vector<SubstitutionParamMapping> &get_substs () const;
// the substitions we have here define X,Y but the arguments have no bindings
// so its a matter of ordering
SubstitutionArgumentMappings
- get_mappings_from_generic_args (HIR::GenericArgs &args);
+ get_mappings_from_generic_args (HIR::GenericArgs &args,
+ const std::vector<Region> ®ions);
// Recursive substitutions
// Foo <A,B> { a:A, b: B}; Bar <X,Y,Z>{a:X, b: Foo<Y,Z>}
virtual BaseType *handle_substitions (SubstitutionArgumentMappings &mappings)
= 0;
- SubstitutionArgumentMappings get_used_arguments () const;
+ WARN_UNUSED_RESULT const SubstitutionArgumentMappings &
+ get_used_arguments () const;
+
+ WARN_UNUSED_RESULT tl::optional<SubstitutionArg> get_arg_at (size_t i) const;
protected:
std::vector<SubstitutionParamMapping> substitutions;
{
TyVar elm = ref->get_var_element_type ().monomorphized_clone ();
return new ReferenceType (ref->get_ref (), ref->get_ty_ref (), elm,
- ref->mutability (), ref->get_combined_refs ());
+ ref->mutability (), ref->get_region (),
+ ref->get_combined_refs ());
}
else if (auto tuple = x->try_as<const TupleType> ())
{
return new FnType (fn->get_ref (), fn->get_ty_ref (), fn->get_id (),
fn->get_identifier (), fn->ident, fn->get_flags (),
fn->get_abi (), std::move (cloned_params), retty,
- fn->clone_substs (), fn->get_combined_refs ());
+ fn->clone_substs (), fn->get_substitution_arguments (),
+ fn->get_combined_refs ());
}
else if (auto fn = x->try_as<const FnPtr> ())
{
auto context = Resolver::TypeCheckContext::get ();
bool ok = false;
+ // NOTE: Calling this error is misleading.
if (default_hint.kind == TypeKind::ERROR)
{
switch (infer_kind)
return new FnType (get_ref (), get_ty_ref (), get_id (), get_identifier (),
ident, flags, abi, std::move (cloned_params),
get_return_type ()->clone (), clone_substs (),
- get_combined_refs ());
+ get_substitution_arguments (), get_combined_refs ());
}
FnType *
// Reference Type
ReferenceType::ReferenceType (HirId ref, TyVar base, Mutability mut,
- std::set<HirId> refs)
+ Region region, std::set<HirId> refs)
: BaseType (ref, ref, KIND,
{Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
- refs),
- base (base), mut (mut)
+ std::move (refs)),
+ base (base), mut (mut), region (region)
{}
ReferenceType::ReferenceType (HirId ref, HirId ty_ref, TyVar base,
- Mutability mut, std::set<HirId> refs)
+ Mutability mut, Region region,
+ std::set<HirId> refs)
: BaseType (ref, ty_ref, KIND,
{Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
- refs),
- base (base), mut (mut)
+ std::move (refs)),
+ base (base), mut (mut), region (region)
{}
Mutability
{
return mut == Mutability::Mut;
}
+Region
+ReferenceType::get_region () const
+{
+ return region;
+}
bool
ReferenceType::is_dyn_object () const
ReferenceType::clone () const
{
return new ReferenceType (get_ref (), get_ty_ref (), base, mutability (),
- get_combined_refs ());
+ get_region (), get_combined_refs ());
}
ReferenceType *
#include "rust-tyty-bounds.h"
#include "rust-tyty-util.h"
#include "rust-tyty-subst.h"
+#include "rust-tyty-region.h"
+
+#include <limits>
namespace Rust {
uint8_t flags, ABI abi,
std::vector<std::pair<HIR::Pattern *, BaseType *>> params,
BaseType *type, std::vector<SubstitutionParamMapping> subst_refs,
+ SubstitutionArgumentMappings substitution_argument_mappings,
std::set<HirId> refs = std::set<HirId> ())
: CallableTypeInterface (ref, ref, TypeKind::FNDEF, ident, refs),
- SubstitutionRef (std::move (subst_refs),
- SubstitutionArgumentMappings::error ()),
+ SubstitutionRef (std::move (subst_refs), substitution_argument_mappings),
params (std::move (params)), type (type), flags (flags),
identifier (identifier), id (id), abi (abi)
{
RustIdent ident, uint8_t flags, ABI abi,
std::vector<std::pair<HIR::Pattern *, BaseType *>> params,
BaseType *type, std::vector<SubstitutionParamMapping> subst_refs,
+ SubstitutionArgumentMappings substitution_argument_mappings,
std::set<HirId> refs = std::set<HirId> ())
: CallableTypeInterface (ref, ty_ref, TypeKind::FNDEF, ident, refs),
- SubstitutionRef (std::move (subst_refs),
- SubstitutionArgumentMappings::error ()),
+ SubstitutionRef (std::move (subst_refs), substitution_argument_mappings),
params (params), type (type), flags (flags), identifier (identifier),
id (id), abi (abi)
{
= std::vector<TypeBoundPredicate> ())
: CallableTypeInterface (ref, ty_ref, TypeKind::CLOSURE, ident, refs),
SubstitutionRef (std::move (subst_refs),
- SubstitutionArgumentMappings::error ()),
+ SubstitutionArgumentMappings::error ()), // TODO
parameters (parameters), result_type (std::move (result_type)), id (id),
captures (captures)
{
class ReferenceType : public BaseType
{
public:
- static constexpr auto KIND = TypeKind::REF;
+ static constexpr auto KIND = REF;
ReferenceType (HirId ref, TyVar base, Mutability mut,
+ Region region = Region::make_anonymous (),
std::set<HirId> refs = std::set<HirId> ());
ReferenceType (HirId ref, HirId ty_ref, TyVar base, Mutability mut,
+ Region region = Region::make_anonymous (),
std::set<HirId> refs = std::set<HirId> ());
BaseType *get_base () const;
Mutability mutability () const;
bool is_mutable () const;
+ WARN_UNUSED_RESULT Region get_region () const;
+ void set_region (Region region);
+
bool is_dyn_object () const;
bool is_dyn_slice_type (const TyTy::SliceType **slice = nullptr) const;
bool is_dyn_str_type (const TyTy::StrType **str = nullptr) const;
private:
TyVar base;
Mutability mut;
+ Region region;
};
class PointerType : public BaseType