blob: c69a8287de27a5616f4affa3806bb0a44f399130 [file] [log] [blame]
// Copyright (C) 2020-2024 Free Software Foundation, Inc.
// This file is part of GCC.
// GCC is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 3, or (at your option) any later
// version.
// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
// You should have received a copy of the GNU General Public License
// along with GCC; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
#ifndef RUST_AST_RESOLVE_TYPE_H
#define RUST_AST_RESOLVE_TYPE_H
#include "rust-ast-resolve-base.h"
#include "rust-ast-resolve-expr.h"
namespace Rust {
namespace Resolver {
class ResolveRelativeTypePath
{
public:
static bool go (AST::TypePath &path, NodeId &resolved_node_id);
};
class ResolveRelativeQualTypePath : public ResolverBase
{
using ResolverBase::visit;
public:
static bool go (AST::QualifiedPathInType &path);
void visit (AST::TypePathSegmentGeneric &seg) override;
void visit (AST::TypePathSegment &seg) override;
protected:
bool resolve_qual_seg (AST::QualifiedPathType &seg);
private:
ResolveRelativeQualTypePath ();
bool failure_flag;
};
class ResolveType : public ResolverBase
{
using Rust::Resolver::ResolverBase::visit;
public:
static NodeId go (AST::Type *type)
{
ResolveType resolver;
type->accept_vis (resolver);
return resolver.resolved_node;
}
void visit (AST::BareFunctionType &fntype) override
{
for (auto &param : fntype.get_function_params ())
ResolveType::go (param.get_type ().get ());
if (fntype.has_return_type ())
ResolveType::go (fntype.get_return_type ().get ());
}
void visit (AST::TupleType &tuple) override
{
if (tuple.is_unit_type ())
{
resolved_node = resolver->get_unit_type_node_id ();
return;
}
for (auto &elem : tuple.get_elems ())
ResolveType::go (elem.get ());
}
void visit (AST::TypePath &path) override
{
ResolveRelativeTypePath::go (path, resolved_node);
}
void visit (AST::QualifiedPathInType &path) override
{
ResolveRelativeQualTypePath::go (path);
}
void visit (AST::ArrayType &type) override;
void visit (AST::ReferenceType &type) override;
void visit (AST::InferredType &type) override;
void visit (AST::NeverType &type) override;
void visit (AST::RawPointerType &type) override;
void visit (AST::TraitObjectTypeOneBound &type) override;
void visit (AST::TraitObjectType &type) override;
void visit (AST::SliceType &type) override;
private:
ResolveType () : ResolverBase () {}
};
class ResolveTypeBound : public ResolverBase
{
using Rust::Resolver::ResolverBase::visit;
public:
static NodeId go (AST::TypeParamBound *type)
{
ResolveTypeBound resolver;
type->accept_vis (resolver);
return resolver.resolved_node;
};
void visit (AST::TraitBound &bound) override
{
resolved_node = ResolveType::go (&bound.get_type_path ());
}
private:
ResolveTypeBound () : ResolverBase () {}
};
class ResolveGenericParam : public ResolverBase
{
using Rust::Resolver::ResolverBase::visit;
public:
static NodeId go (AST::GenericParam *param, const CanonicalPath &prefix,
const CanonicalPath &canonical_prefix)
{
ResolveGenericParam resolver (prefix, canonical_prefix);
param->accept_vis (resolver);
return resolver.resolved_node;
}
void visit (AST::ConstGenericParam &param) override
{
ResolveType::go (param.get_type ().get ());
if (param.has_default_value ())
ResolveExpr::go (param.get_default_value ().get_expression ().get (),
prefix, canonical_prefix);
ok = true;
}
void visit (AST::TypeParam &param) override
{
// if it has a type lets resolve it
if (param.has_type ())
ResolveType::go (param.get_type ().get ());
if (param.has_type_param_bounds ())
{
for (auto &bound : param.get_type_param_bounds ())
{
ResolveTypeBound::go (bound.get ());
}
}
auto seg
= CanonicalPath::new_seg (param.get_node_id (),
param.get_type_representation ().as_string ());
resolver->get_type_scope ().insert (
seg, param.get_node_id (), param.get_locus (), false, Rib::ItemType::Type,
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rust_error_at (param.get_locus (),
"generic param redefined multiple times");
rust_error_at (locus, "was defined here");
});
mappings->insert_canonical_path (param.get_node_id (), seg);
}
private:
ResolveGenericParam (const CanonicalPath &prefix,
const CanonicalPath &canonical_prefix)
: ResolverBase (), ok (false), prefix (prefix),
canonical_prefix (canonical_prefix)
{}
bool ok;
const CanonicalPath &prefix;
const CanonicalPath &canonical_prefix;
};
class ResolveWhereClause : public ResolverBase
{
using Rust::Resolver::ResolverBase::visit;
public:
static void Resolve (AST::WhereClause &where_clause)
{
ResolveWhereClause r;
for (auto &clause : where_clause.get_items ())
clause->accept_vis (r);
}
void visit (AST::TypeBoundWhereClauseItem &item) override
{
ResolveType::go (item.get_type ().get ());
if (item.has_type_param_bounds ())
{
for (auto &bound : item.get_type_param_bounds ())
{
ResolveTypeBound::go (bound.get ());
}
}
}
private:
ResolveWhereClause () : ResolverBase () {}
};
class ResolveTypeToCanonicalPath : public ResolverBase
{
using Rust::Resolver::ResolverBase::visit;
public:
static bool go (AST::Type *type, CanonicalPath &result);
void visit (AST::TypePath &path) override;
void visit (AST::ReferenceType &type) override;
void visit (AST::RawPointerType &type) override;
void visit (AST::SliceType &type) override;
void visit (AST::TraitObjectTypeOneBound &type) override;
void visit (AST::TraitObjectType &type) override;
private:
ResolveTypeToCanonicalPath ();
CanonicalPath result;
};
class ResolveGenericArgs : public ResolverBase
{
using Rust::Resolver::ResolverBase::visit;
public:
static void go (AST::GenericArgs &generic_args);
static void go (AST::GenericArgs &generic_args, const CanonicalPath &prefix,
const CanonicalPath &canonical_prefix);
private:
ResolveGenericArgs (const CanonicalPath &prefix,
const CanonicalPath &canonical_prefix)
: ResolverBase (), prefix (prefix), canonical_prefix (canonical_prefix)
{}
bool is_type_name (const CanonicalPath &path);
bool is_const_value_name (const CanonicalPath &path);
/**
* Resolve a disambiguated generic arg
*/
void disambiguate (AST::GenericArg &arg);
/**
* Resolve a disambiguated generic arg
*/
void resolve_disambiguated_generic (AST::GenericArg &arg);
const CanonicalPath &prefix;
const CanonicalPath &canonical_prefix;
};
} // namespace Resolver
} // namespace Rust
#endif // RUST_AST_RESOLVE_TYPE_H