// The one exception is the implicit Self type of a trait
bool apply_sized = !is_self;
auto param_type
- = TypeResolveGenericParam::Resolve (*generic_param, apply_sized);
+ = TypeResolveGenericParam::Resolve (*generic_param, true,
+ apply_sized);
+
context->insert_type (generic_param->get_mappings (), param_type);
substitutions.push_back (
TyTy::SubstitutionParamMapping (typaram, param_type));
context (TypeCheckContext::get ())
{}
+void
+TypeCheckBase::ResolveGenericParams (
+ const std::vector<std::unique_ptr<HIR::GenericParam>> &generic_params,
+ std::vector<TyTy::SubstitutionParamMapping> &substitutions, bool is_foreign,
+ ABI abi)
+{
+ TypeCheckBase ctx;
+ ctx.resolve_generic_params (generic_params, substitutions, is_foreign, abi);
+}
+
static void
walk_types_to_constrain (std::set<HirId> &constrained_symbols,
const TyTy::SubstitutionArgumentMappings &constraints)
void
TypeCheckBase::resolve_generic_params (
const std::vector<std::unique_ptr<HIR::GenericParam>> &generic_params,
- std::vector<TyTy::SubstitutionParamMapping> &substitutions)
+ std::vector<TyTy::SubstitutionParamMapping> &substitutions, bool is_foreign,
+ ABI abi)
{
for (auto &generic_param : generic_params)
{
context->get_lifetime_resolver ().insert_mapping (
context->intern_lifetime (lifetime));
}
-
break;
case HIR::GenericParam::GenericKind::CONST: {
+ if (is_foreign && abi != Rust::ABI::INTRINSIC)
+ {
+ rust_error_at (generic_param->get_locus (), ErrorCode::E0044,
+ "foreign items may not have const parameters");
+ }
+
auto ¶m
= static_cast<HIR::ConstGenericParam &> (*generic_param);
auto specified_type = TypeCheckType::Resolve (param.get_type ());
break;
case HIR::GenericParam::GenericKind::TYPE: {
- auto param_type = TypeResolveGenericParam::Resolve (*generic_param);
+ if (is_foreign && abi != Rust::ABI::INTRINSIC)
+ {
+ rust_error_at (generic_param->get_locus (), ErrorCode::E0044,
+ "foreign items may not have type parameters");
+ }
+
+ auto param_type = TypeResolveGenericParam::Resolve (
+ *generic_param, false /*resolve_trait_bounds*/);
context->insert_type (generic_param->get_mappings (), param_type);
- substitutions.push_back (TyTy::SubstitutionParamMapping (
- static_cast<HIR::TypeParam &> (*generic_param), param_type));
+ auto ¶m = static_cast<HIR::TypeParam &> (*generic_param);
+ TyTy::SubstitutionParamMapping p (param, param_type);
+ substitutions.push_back (p);
}
break;
}
}
+
+ // now walk them to setup any specified type param bounds
+ for (auto &subst : substitutions)
+ {
+ auto pty = subst.get_param_ty ();
+ TypeResolveGenericParam::ApplyAnyTraitBounds (subst.get_generic_param (),
+ pty);
+ }
}
TyTy::TypeBoundPredicate
public:
virtual ~TypeCheckBase () {}
+ static void ResolveGenericParams (
+ const std::vector<std::unique_ptr<HIR::GenericParam>> &generic_params,
+ std::vector<TyTy::SubstitutionParamMapping> &substitutions, bool is_foreign,
+ ABI abi);
+
protected:
TypeCheckBase ();
void resolve_generic_params (
const std::vector<std::unique_ptr<HIR::GenericParam>> &generic_params,
- std::vector<TyTy::SubstitutionParamMapping> &substitutions);
+ std::vector<TyTy::SubstitutionParamMapping> &substitutions,
+ bool is_foreign = false, ABI abi = ABI::RUST);
TyTy::TypeBoundPredicate get_marker_predicate (LangItem::Kind item_type,
location_t locus);
std::vector<TyTy::SubstitutionParamMapping> substitutions;
if (function.has_generics ())
{
- for (auto &generic_param : function.get_generic_params ())
- {
- 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.
- if (parent.get_abi () != Rust::ABI::INTRINSIC)
- {
- rust_error_at (function.get_locus (), ErrorCode::E0044,
- "foreign items may not have const parameters");
- }
- break;
-
- case HIR::GenericParam::GenericKind::TYPE: {
- if (parent.get_abi () != Rust::ABI::INTRINSIC)
- {
- rust_error_at (
- function.get_locus (), ErrorCode::E0044,
- "foreign items may not have type parameters");
- }
- auto param_type
- = TypeResolveGenericParam::Resolve (*generic_param);
- context->insert_type (generic_param->get_mappings (),
- param_type);
-
- substitutions.push_back (TyTy::SubstitutionParamMapping (
- static_cast<HIR::TypeParam &> (*generic_param), param_type));
- }
- break;
- }
- }
+ resolve_generic_params (function.get_generic_params (), substitutions,
+ true /*is_foreign*/, parent.get_abi ());
}
TyTy::RegionConstraints region_constraints;
TypeCheckTopLevelExternItem::visit (HIR::ExternalTypeItem &type)
{
rust_sorry_at (type.get_locus (), "extern types are not supported yet");
- // auto binder_pin = context->push_clean_lifetime_resolver ();
-
- // std::vector<TyTy::SubstitutionParamMapping> substitutions;
- // if (function.has_generics ())
- // {
- // for (auto &generic_param : function.get_generic_params ())
- // {
- // 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.
- // break;
-
- // case HIR::GenericParam::GenericKind::TYPE: {
- // auto param_type
- // = TypeResolveGenericParam::Resolve (generic_param.get ());
- // context->insert_type (generic_param->get_mappings (),
- // param_type);
-
- // substitutions.push_back (TyTy::SubstitutionParamMapping (
- // static_cast<HIR::TypeParam &> (*generic_param), param_type));
- // }
- // break;
- // }
- // }
- // }
-
- // TyTy::RegionConstraints region_constraints;
- // if (function.has_where_clause ())
- // {
- // for (auto &where_clause_item : function.get_where_clause ().get_items
- // ())
- // {
- // ResolveWhereClauseItem::Resolve (*where_clause_item.get (),
- // region_constraints);
- // }
- // }
-
- // TyTy::BaseType *ret_type = nullptr;
- // if (!function.has_return_type ())
- // ret_type
- // = TyTy::TupleType::get_unit_type (function.get_mappings ().get_hirid
- // ());
- // else
- // {
- // auto resolved
- // = TypeCheckType::Resolve (function.get_return_type ().get ());
- // if (resolved == nullptr)
- // {
- // rust_error_at (function.get_locus (),
- // "failed to resolve return type");
- // return;
- // }
-
- // ret_type = resolved->clone ();
- // ret_type->set_ref (
- // function.get_return_type ()->get_mappings ().get_hirid ());
- // }
-
- // std::vector<std::pair<HIR::Pattern *, TyTy::BaseType *> > params;
- // for (auto ¶m : function.get_function_params ())
- // {
- // // get the name as well required for later on
- // auto param_tyty = TypeCheckType::Resolve (param.get_type ().get ());
-
- // // these are implicit mappings and not used
- // auto crate_num = mappings->get_current_crate ();
- // Analysis::NodeMapping mapping (crate_num, mappings->get_next_node_id
- // (),
- // mappings->get_next_hir_id (crate_num),
- // UNKNOWN_LOCAL_DEFID);
-
- // HIR::IdentifierPattern *param_pattern
- // = new HIR::IdentifierPattern (mapping, param.get_param_name (),
- // UNDEF_LOCATION, false, Mutability::Imm,
- // std::unique_ptr<HIR::Pattern> (nullptr));
-
- // params.push_back (
- // std::pair<HIR::Pattern *, TyTy::BaseType *> (param_pattern,
- // param_tyty));
-
- // context->insert_type (param.get_mappings (), param_tyty);
-
- // // FIXME do we need error checking for patterns here?
- // // see https://github.com/Rust-GCC/gccrs/issues/995
- // }
-
- // uint8_t flags = TyTy::FnType::FNTYPE_IS_EXTERN_FLAG;
- // if (function.is_variadic ())
- // {
- // flags |= TyTy::FnType::FNTYPE_IS_VARADIC_FLAG;
- // if (parent.get_abi () != Rust::ABI::C)
- // {
- // rust_error_at (
- // function.get_locus (), ErrorCode::E0045,
- // "C-variadic function must have C or cdecl calling convention");
- // }
- // }
-
- // RustIdent ident{
- // CanonicalPath::new_seg (function.get_mappings ().get_nodeid (),
- // 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),
- // TyTy::SubstitutionArgumentMappings::empty (
- // context->get_lifetime_resolver ().get_num_bound_regions ()),
- // region_constraints);
-
- // context->insert_type (function.get_mappings (), fnType);
- // resolved = fnType;
+ // TODO
}
TypeCheckImplItem::TypeCheckImplItem (
TyTy::BaseType *lookup = nullptr;
if (!query_type (ref, &lookup))
{
- if (is_root)
+ if (is_root || root_tyty == nullptr)
{
rust_error_at (expr.get_locus (), ErrorCode::E0425,
"cannot find value %qs in this scope",
TyTy::BaseType *lookup = nullptr;
if (!query_type (ref, &lookup))
{
- if (is_root)
- return new TyTy::ErrorType (path.get_mappings ().get_hirid ());
+ if (is_root || root_tyty == nullptr)
+ {
+ rust_error_at (seg->get_locus (),
+ "failed to resolve type path segment: %qs",
+ seg->as_string ().c_str ());
+ return new TyTy::ErrorType (path.get_mappings ().get_hirid ());
+ }
return root_tyty;
}
ignore_mandatory_trait_items);
if (candidates.size () == 0)
{
+ prev_segment->debug ();
rust_error_at (
seg->get_locus (),
"failed to resolve path segment using an impl Probe");
}
TyTy::ParamType *
-TypeResolveGenericParam::Resolve (HIR::GenericParam ¶m, bool apply_sized)
+TypeResolveGenericParam::Resolve (HIR::GenericParam ¶m,
+ bool resolve_trait_bounds, bool apply_sized)
{
- TypeResolveGenericParam resolver (apply_sized);
+ TypeResolveGenericParam resolver (apply_sized, resolve_trait_bounds);
switch (param.get_kind ())
{
case HIR::GenericParam::GenericKind::TYPE:
return resolver.resolved;
}
+void
+TypeResolveGenericParam::ApplyAnyTraitBounds (HIR::TypeParam ¶m,
+ TyTy::ParamType *pty)
+{
+ TypeResolveGenericParam resolver (true, true);
+ resolver.apply_trait_bounds (param, pty);
+}
+
void
TypeResolveGenericParam::visit (HIR::LifetimeParam ¶m)
{
if (param.has_type ())
TypeCheckType::Resolve (param.get_type ());
+ resolved
+ = new TyTy::ParamType (param.get_type_representation ().as_string (),
+ param.get_locus (),
+ param.get_mappings ().get_hirid (), param, {});
+
+ if (resolve_trait_bounds)
+ apply_trait_bounds (param, resolved);
+}
+
+void
+TypeResolveGenericParam::apply_trait_bounds (HIR::TypeParam ¶m,
+ TyTy::ParamType *pty)
+{
std::unique_ptr<HIR::Type> implicit_self_bound = nullptr;
if (param.has_type_param_bounds ())
{
//
// We can only do this when we are not resolving the implicit Self for Sized
// itself
- rust_debug_loc (param.get_locus (), "apply_sized: %s",
- apply_sized ? "true" : "false");
if (apply_sized)
{
TyTy::TypeBoundPredicate sized_predicate
}
}
- resolved = new TyTy::ParamType (param.get_type_representation ().as_string (),
- param.get_locus (),
- param.get_mappings ().get_hirid (), param,
- specified_bounds);
+ // inherit them
+ pty->inherit_bounds (specified_bounds);
}
void
{
public:
static TyTy::ParamType *Resolve (HIR::GenericParam ¶m,
+ bool resolve_trait_bounds = true,
bool apply_sized = true);
+ static void ApplyAnyTraitBounds (HIR::TypeParam ¶m, TyTy::ParamType *pty);
+
protected:
void visit (HIR::TypeParam ¶m);
void visit (HIR::LifetimeParam ¶m);
void visit (HIR::ConstGenericParam ¶m);
+ void apply_trait_bounds (HIR::TypeParam ¶m, TyTy::ParamType *pty);
+
private:
- TypeResolveGenericParam (bool apply_sized)
- : TypeCheckBase (), resolved (nullptr), apply_sized (apply_sized)
+ TypeResolveGenericParam (bool apply_sized, bool resolve_trait_bounds)
+ : TypeCheckBase (), resolved (nullptr), apply_sized (apply_sized),
+ resolve_trait_bounds (resolve_trait_bounds)
{}
TyTy::ParamType *resolved;
bool apply_sized;
+ bool resolve_trait_bounds;
};
class ResolveWhereClauseItem : public TypeCheckBase
HIR::TraitFunctionDecl &function = fn.get_decl ();
if (function.has_generics ())
{
- for (auto &generic_param : function.get_generic_params ())
- {
- switch (generic_param.get ()->get_kind ())
- {
- 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::GenericParam::GenericKind::TYPE: {
- auto param_type
- = TypeResolveGenericParam::Resolve (*generic_param);
- context->insert_type (generic_param->get_mappings (),
- param_type);
-
- substitutions.push_back (TyTy::SubstitutionParamMapping (
- static_cast<HIR::TypeParam &> (*generic_param), param_type));
- }
- break;
- }
- }
+ TypeCheckBase::ResolveGenericParams (function.get_generic_params (),
+ substitutions, false /*is_foreign*/,
+ ABI::RUST);
}
if (function.has_where_clause ())
#include "rust-hir-type-check-implitem.h"
#include "rust-hir-type-check-item.h"
#include "rust-hir-type-check.h"
+#include "rust-hir-type-check-type.h"
#include "rust-casts.h"
#include "rust-unify.h"
#include "rust-coercion.h"
#include "rust-hir-type-bounds.h"
+#include "rust-immutable-name-resolution-context.h"
+#include "options.h"
namespace Rust {
namespace Resolver {
query_type (HirId reference, TyTy::BaseType **result)
{
auto &mappings = Analysis::Mappings::get ();
+ auto &resolver = *Resolver::get ();
TypeCheckContext *context = TypeCheckContext::get ();
if (context->query_in_progress (reference))
HIR::ImplBlock *impl = impl_block_by_type.value ();
rust_debug_loc (impl->get_locus (), "resolved impl block type {%u} to",
reference);
+
+ // this could be recursive to the root type
+ if (impl->has_type ())
+ {
+ HIR::Type &ty = impl->get_type ();
+ NodeId ref_node_id = UNKNOWN_NODEID;
+ NodeId ast_node_id = ty.get_mappings ().get_nodeid ();
+
+ if (flag_name_resolution_2_0)
+ {
+ auto &nr_ctx = Resolver2_0::ImmutableNameResolutionContext::get ()
+ .resolver ();
+
+ // assign the ref_node_id if we've found something
+ nr_ctx.lookup (ast_node_id)
+ .map (
+ [&ref_node_id] (NodeId resolved) { ref_node_id = resolved; });
+ }
+ else if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
+ resolver.lookup_resolved_type (ast_node_id, &ref_node_id);
+
+ if (ref_node_id != UNKNOWN_NODEID)
+ {
+ tl::optional<HirId> hid
+ = mappings.lookup_node_to_hir (ref_node_id);
+ if (hid.has_value () && context->query_in_progress (hid.value ()))
+ {
+ context->query_completed (reference);
+ return false;
+ }
+ }
+ }
+
*result = TypeCheckItem::ResolveImplBlockSelf (*impl);
context->query_completed (reference);
return true;
namespace Rust {
namespace TyTy {
-SubstitutionParamMapping::SubstitutionParamMapping (
- const HIR::TypeParam &generic, ParamType *param)
+SubstitutionParamMapping::SubstitutionParamMapping (HIR::TypeParam &generic,
+ ParamType *param)
: generic (generic), param (param)
{}
return param;
}
-const HIR::TypeParam &
-SubstitutionParamMapping::get_generic_param () const
+HIR::TypeParam &
+SubstitutionParamMapping::get_generic_param ()
{
return generic;
}
class SubstitutionParamMapping
{
public:
- SubstitutionParamMapping (const HIR::TypeParam &generic, ParamType *param);
+ SubstitutionParamMapping (HIR::TypeParam &generic, ParamType *param);
SubstitutionParamMapping (const SubstitutionParamMapping &other);
const ParamType *get_param_ty () const;
- const HIR::TypeParam &get_generic_param () const;
+ HIR::TypeParam &get_generic_param ();
// this is used for the backend to override the HirId ref of the param to
// what the concrete type is for the rest of the context
bool need_substitution () const;
private:
- const HIR::TypeParam &generic;
+ HIR::TypeParam &generic;
ParamType *param;
};
first_lifetime = lookup_or_add_type (ty.get_orig_ref ());
first_type = first_lifetime + ty.get_used_arguments ().get_regions ().size ();
- for (const auto ¶m : ty.get_substs ())
+ for (auto ¶m : ty.get_substs ())
param_names.push_back (
param.get_generic_param ().get_type_representation ().as_string ());
--- /dev/null
+type A = crate::A;
+// { dg-error "failed to resolve type path segment: .A." "" { target *-*-* } .-2 }