aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/backend/rust-compile-context.h2
-rw-r--r--gcc/rust/backend/rust-mangle.cc79
-rw-r--r--gcc/rust/backend/rust-mangle.h3
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-base.h5
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-expr.h119
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-implitem.h86
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-item.h287
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-pattern.cc6
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-stmt.h110
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-struct-expr-field.h15
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-toplevel.h167
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.h82
-rw-r--r--gcc/rust/resolve/rust-ast-resolve.cc57
-rw-r--r--gcc/rust/resolve/rust-name-resolver.h2
-rw-r--r--gcc/rust/rust-session-manager.cc2
-rw-r--r--gcc/rust/util/rust-canonical-path.h36
-rw-r--r--gcc/testsuite/rust/compile/canonical_paths1.rs25
-rw-r--r--gcc/testsuite/rust/compile/torture/mod3.rs17
-rw-r--r--gcc/testsuite/rust/compile/traits9.rs2
19 files changed, 833 insertions, 269 deletions
diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h
index b6f76ab..46f88b3 100644
--- a/gcc/rust/backend/rust-compile-context.h
+++ b/gcc/rust/backend/rust-compile-context.h
@@ -304,7 +304,7 @@ public:
std::string mangle_item (const TyTy::BaseType *ty,
const Resolver::CanonicalPath &path) const
{
- return mangler.mangle_item (ty, path, mappings->get_current_crate_name ());
+ return mangler.mangle_item (ty, path);
}
private:
diff --git a/gcc/rust/backend/rust-mangle.cc b/gcc/rust/backend/rust-mangle.cc
index 26c760e..eaf7814 100644
--- a/gcc/rust/backend/rust-mangle.cc
+++ b/gcc/rust/backend/rust-mangle.cc
@@ -9,6 +9,9 @@ static const std::string kMangledSymbolDelim = "E";
static const std::string kMangledGenericDelim = "$C$";
static const std::string kMangledSubstBegin = "$LT$";
static const std::string kMangledSubstEnd = "$GT$";
+static const std::string kMangledSpace = "$u20$";
+static const std::string kMangledRef = "$RF$";
+static const std::string kQualPathBegin = "_" + kMangledSubstBegin;
namespace Rust {
namespace Compile {
@@ -22,17 +25,35 @@ legacy_mangle_name (const std::string &name)
// <&T as core::fmt::Debug>::fmt:
// _ZN42_$LT$$RF$T$u20$as$u20$core..fmt..Debug$GT$3fmt17h6dac924c0051eef7E
// replace all white space with $ and & with RF
-
+ //
+ // <example::Bar as example::A>::fooA:
+ // _ZN43_$LT$example..Bar$u20$as$u20$example..A$GT$4fooA17hfc615fa76c7db7a0E:
+ //
+ // example::Foo<T>::new:
+ // _ZN7example12Foo$LT$T$GT$3new17h9a2aacb7fd783515E:
std::string buffer;
- for (const auto &c : name)
+ for (size_t i = 0; i < name.size (); i++)
{
std::string m;
+ char c = name.at (i);
+
if (c == ' ')
- m = "$";
+ m = kMangledSpace;
else if (c == '&')
- m = "RF";
- else if (c == '<' || c == '>')
- m = "..";
+ m = kMangledRef;
+ else if (i == 0 && c == '<')
+ m = kQualPathBegin;
+ else if (c == '<')
+ m = kMangledSubstBegin;
+ else if (c == '>')
+ m = kMangledSubstEnd;
+ else if (c == ':')
+ {
+ rust_assert (i + 1 < name.size ());
+ rust_assert (name.at (i + 1) == ':');
+ i++;
+ m = "..";
+ }
else
m.push_back (c);
@@ -46,10 +67,11 @@ static std::string
legacy_mangle_canonical_path (const Resolver::CanonicalPath &path)
{
std::string buffer;
- path.iterate_segs ([&] (const Resolver::CanonicalPath &p) -> bool {
- buffer += legacy_mangle_name (p.get ());
- return true;
- });
+ for (size_t i = 0; i < path.size (); i++)
+ {
+ auto &seg = path.get_seg_at (i);
+ buffer += legacy_mangle_name (seg.second);
+ }
return buffer;
}
@@ -150,7 +172,8 @@ v0_simple_type_prefix (const TyTy::BaseType *ty)
// Add an underscore-terminated base62 integer to the mangling string.
// This corresponds to the `<base-62-number>` grammar in the v0 mangling RFC:
// - 0 is encoded as "_"
-// - any other value is encoded as itself minus one in base 62, followed by "_"
+// - any other value is encoded as itself minus one in base 62, followed by
+// "_"
static void
v0_add_integer_62 (std::string &mangled, uint64_t x)
{
@@ -188,11 +211,11 @@ v0_add_identifier (std::string &mangled, const std::string &identifier)
{
// FIXME: gccrs cannot handle unicode identifiers yet, so we never have to
// create mangling for unicode values for now. However, this is handled
- // by the v0 mangling scheme. The grammar for unicode identifier is contained
- // in <undisambiguated-identifier>, right under the <identifier> one. If the
- // identifier contains unicode values, then an extra "u" needs to be added
- // to the mangling string and `punycode` must be used to encode the
- // characters.
+ // by the v0 mangling scheme. The grammar for unicode identifier is
+ // contained in <undisambiguated-identifier>, right under the <identifier>
+ // one. If the identifier contains unicode values, then an extra "u" needs
+ // to be added to the mangling string and `punycode` must be used to encode
+ // the characters.
mangled += std::to_string (identifier.size ());
@@ -217,22 +240,25 @@ v0_type_prefix (const TyTy::BaseType *ty)
static std::string
legacy_mangle_item (const TyTy::BaseType *ty,
- const Resolver::CanonicalPath &path,
- const std::string &crate_name)
+ const Resolver::CanonicalPath &path)
{
const std::string hash = legacy_hash (ty->as_string ());
const std::string hash_sig = legacy_mangle_name (hash);
- return kMangledSymbolPrefix + legacy_mangle_name (crate_name)
- + legacy_mangle_canonical_path (path) + hash_sig + kMangledSymbolDelim;
+ return kMangledSymbolPrefix + legacy_mangle_canonical_path (path) + hash_sig
+ + kMangledSymbolDelim;
}
static std::string
-v0_mangle_item (const TyTy::BaseType *ty, const Resolver::CanonicalPath &path,
- const std::string &crate_name)
+v0_mangle_item (const TyTy::BaseType *ty, const Resolver::CanonicalPath &path)
{
- std::string mangled;
+ // we can get this from the canonical_path
+ auto mappings = Analysis::Mappings::get ();
+ std::string crate_name;
+ bool ok = mappings->get_crate_name (path.get_crate_num (), crate_name);
+ rust_assert (ok);
+ std::string mangled;
// FIXME: Add real algorithm once all pieces are implemented
auto ty_prefix = v0_type_prefix (ty);
v0_add_identifier (mangled, crate_name);
@@ -243,15 +269,14 @@ v0_mangle_item (const TyTy::BaseType *ty, const Resolver::CanonicalPath &path,
std::string
Mangler::mangle_item (const TyTy::BaseType *ty,
- const Resolver::CanonicalPath &path,
- const std::string &crate_name) const
+ const Resolver::CanonicalPath &path) const
{
switch (version)
{
case Mangler::MangleVersion::LEGACY:
- return legacy_mangle_item (ty, path, crate_name);
+ return legacy_mangle_item (ty, path);
case Mangler::MangleVersion::V0:
- return v0_mangle_item (ty, path, crate_name);
+ return v0_mangle_item (ty, path);
default:
gcc_unreachable ();
}
diff --git a/gcc/rust/backend/rust-mangle.h b/gcc/rust/backend/rust-mangle.h
index 0cc7f76..03e1dc6 100644
--- a/gcc/rust/backend/rust-mangle.h
+++ b/gcc/rust/backend/rust-mangle.h
@@ -34,8 +34,7 @@ public:
// this needs to support Legacy and V0 see github #429 or #305
std::string mangle_item (const TyTy::BaseType *ty,
- const Resolver::CanonicalPath &path,
- const std::string &crate_name) const;
+ const Resolver::CanonicalPath &path) const;
static void set_mangling (int frust_mangling_value)
{
diff --git a/gcc/rust/resolve/rust-ast-resolve-base.h b/gcc/rust/resolve/rust-ast-resolve-base.h
index 237a971..6ee5f3d 100644
--- a/gcc/rust/resolve/rust-ast-resolve-base.h
+++ b/gcc/rust/resolve/rust-ast-resolve-base.h
@@ -201,13 +201,14 @@ public:
protected:
ResolverBase (NodeId parent)
- : resolver (Resolver::get ()), resolved_node (UNKNOWN_NODEID),
- parent (parent), locus (Location ())
+ : resolver (Resolver::get ()), mappings (Analysis::Mappings::get ()),
+ resolved_node (UNKNOWN_NODEID), parent (parent), locus (Location ())
{}
bool resolved () const { return resolved_node != UNKNOWN_NODEID; }
Resolver *resolver;
+ Analysis::Mappings *mappings;
NodeId resolved_node;
NodeId parent;
Location locus;
diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.h b/gcc/rust/resolve/rust-ast-resolve-expr.h
index 392f4f4..b7b8646 100644
--- a/gcc/rust/resolve/rust-ast-resolve-expr.h
+++ b/gcc/rust/resolve/rust-ast-resolve-expr.h
@@ -63,15 +63,16 @@ class ResolveExpr : public ResolverBase
using Rust::Resolver::ResolverBase::visit;
public:
- static void go (AST::Expr *expr, NodeId parent)
+ static void go (AST::Expr *expr, NodeId parent, const CanonicalPath &prefix,
+ const CanonicalPath &canonical_prefix)
{
- ResolveExpr resolver (parent);
+ ResolveExpr resolver (parent, prefix, canonical_prefix);
expr->accept_vis (resolver);
};
void visit (AST::TupleIndexExpr &expr) override
{
- ResolveExpr::go (expr.get_tuple_expr ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_tuple_expr ().get (), expr.get_node_id ());
}
void visit (AST::TupleExpr &expr) override
@@ -80,7 +81,7 @@ public:
return;
for (auto &elem : expr.get_tuple_elems ())
- ResolveExpr::go (elem.get (), expr.get_node_id ());
+ resolve_expr (elem.get (), expr.get_node_id ());
}
void visit (AST::PathInExpression &expr) override
@@ -96,20 +97,20 @@ public:
void visit (AST::ReturnExpr &expr) override
{
if (expr.has_returned_expr ())
- ResolveExpr::go (expr.get_returned_expr ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_returned_expr ().get (), expr.get_node_id ());
}
void visit (AST::CallExpr &expr) override
{
- ResolveExpr::go (expr.get_function_expr ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_function_expr ().get (), expr.get_node_id ());
auto const &in_params = expr.get_params ();
for (auto &param : in_params)
- ResolveExpr::go (param.get (), expr.get_node_id ());
+ resolve_expr (param.get (), expr.get_node_id ());
}
void visit (AST::MethodCallExpr &expr) override
{
- ResolveExpr::go (expr.get_receiver_expr ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_receiver_expr ().get (), expr.get_node_id ());
if (expr.get_method_name ().has_generic_args ())
{
@@ -119,13 +120,13 @@ public:
auto const &in_params = expr.get_params ();
for (auto &param : in_params)
- ResolveExpr::go (param.get (), expr.get_node_id ());
+ resolve_expr (param.get (), expr.get_node_id ());
}
void visit (AST::AssignmentExpr &expr) override
{
- ResolveExpr::go (expr.get_left_expr ().get (), expr.get_node_id ());
- ResolveExpr::go (expr.get_right_expr ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_left_expr ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_right_expr ().get (), expr.get_node_id ());
// need to verify the assignee
VerifyAsignee::go (expr.get_left_expr ().get (), expr.get_node_id ());
@@ -160,14 +161,14 @@ public:
void visit (AST::ArithmeticOrLogicalExpr &expr) override
{
- ResolveExpr::go (expr.get_left_expr ().get (), expr.get_node_id ());
- ResolveExpr::go (expr.get_right_expr ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_left_expr ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_right_expr ().get (), expr.get_node_id ());
}
void visit (AST::CompoundAssignmentExpr &expr) override
{
- ResolveExpr::go (expr.get_left_expr ().get (), expr.get_node_id ());
- ResolveExpr::go (expr.get_right_expr ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_left_expr ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_right_expr ().get (), expr.get_node_id ());
// need to verify the assignee
VerifyAsignee::go (expr.get_left_expr ().get (), expr.get_node_id ());
@@ -175,45 +176,45 @@ public:
void visit (AST::ComparisonExpr &expr) override
{
- ResolveExpr::go (expr.get_left_expr ().get (), expr.get_node_id ());
- ResolveExpr::go (expr.get_right_expr ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_left_expr ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_right_expr ().get (), expr.get_node_id ());
}
void visit (AST::LazyBooleanExpr &expr) override
{
- ResolveExpr::go (expr.get_left_expr ().get (), expr.get_node_id ());
- ResolveExpr::go (expr.get_right_expr ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_left_expr ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_right_expr ().get (), expr.get_node_id ());
}
void visit (AST::NegationExpr &expr) override
{
- ResolveExpr::go (expr.get_negated_expr ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_negated_expr ().get (), expr.get_node_id ());
}
void visit (AST::TypeCastExpr &expr) override
{
ResolveType::go (expr.get_type_to_cast_to ().get (), expr.get_node_id ());
- ResolveExpr::go (expr.get_casted_expr ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_casted_expr ().get (), expr.get_node_id ());
}
void visit (AST::IfExpr &expr) override
{
- ResolveExpr::go (expr.get_condition_expr ().get (), expr.get_node_id ());
- ResolveExpr::go (expr.get_if_block ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_condition_expr ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_if_block ().get (), expr.get_node_id ());
}
void visit (AST::IfExprConseqElse &expr) override
{
- ResolveExpr::go (expr.get_condition_expr ().get (), expr.get_node_id ());
- ResolveExpr::go (expr.get_if_block ().get (), expr.get_node_id ());
- ResolveExpr::go (expr.get_else_block ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_condition_expr ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_if_block ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_else_block ().get (), expr.get_node_id ());
}
void visit (AST::IfExprConseqIf &expr) override
{
- ResolveExpr::go (expr.get_condition_expr ().get (), expr.get_node_id ());
- ResolveExpr::go (expr.get_if_block ().get (), expr.get_node_id ());
- ResolveExpr::go (expr.get_conseq_if_expr ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_condition_expr ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_if_block ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_conseq_if_expr ().get (), expr.get_node_id ());
}
void visit (AST::BlockExpr &expr) override;
@@ -226,7 +227,7 @@ public:
void visit (AST::ArrayElemsValues &elems) override
{
for (auto &elem : elems.get_values ())
- ResolveExpr::go (elem.get (), elems.get_node_id ());
+ resolve_expr (elem.get (), elems.get_node_id ());
}
void visit (AST::ArrayExpr &expr) override
@@ -236,52 +237,51 @@ public:
void visit (AST::ArrayIndexExpr &expr) override
{
- ResolveExpr::go (expr.get_array_expr ().get (), expr.get_node_id ());
- ResolveExpr::go (expr.get_index_expr ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_array_expr ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_index_expr ().get (), expr.get_node_id ());
}
void visit (AST::ArrayElemsCopied &elems) override
{
- ResolveExpr::go (elems.get_num_copies ().get (), elems.get_node_id ());
- ResolveExpr::go (elems.get_elem_to_copy ().get (), elems.get_node_id ());
+ resolve_expr (elems.get_num_copies ().get (), elems.get_node_id ());
+ resolve_expr (elems.get_elem_to_copy ().get (), elems.get_node_id ());
}
// this this an empty struct constructor like 'S {}'
void visit (AST::StructExprStruct &struct_expr) override
{
- ResolveExpr::go (&struct_expr.get_struct_name (),
- struct_expr.get_node_id ());
+ resolve_expr (&struct_expr.get_struct_name (), struct_expr.get_node_id ());
}
// this this a struct constructor with fields
void visit (AST::StructExprStructFields &struct_expr) override
{
- ResolveExpr::go (&struct_expr.get_struct_name (),
- struct_expr.get_node_id ());
+ resolve_expr (&struct_expr.get_struct_name (), struct_expr.get_node_id ());
if (struct_expr.has_struct_base ())
{
AST::StructBase &base = struct_expr.get_struct_base ();
- ResolveExpr::go (base.get_base_struct ().get (),
- struct_expr.get_node_id ());
+ resolve_expr (base.get_base_struct ().get (),
+ struct_expr.get_node_id ());
}
auto const &struct_fields = struct_expr.get_fields ();
for (auto &struct_field : struct_fields)
{
ResolveStructExprField::go (struct_field.get (),
- struct_expr.get_node_id ());
+ struct_expr.get_node_id (), prefix,
+ canonical_prefix);
}
}
void visit (AST::GroupedExpr &expr) override
{
- ResolveExpr::go (expr.get_expr_in_parens ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_expr_in_parens ().get (), expr.get_node_id ());
}
void visit (AST::FieldAccessExpr &expr) override
{
- ResolveExpr::go (expr.get_receiver_expr ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_receiver_expr ().get (), expr.get_node_id ());
}
void visit (AST::LoopExpr &expr) override
@@ -311,7 +311,7 @@ public:
Definition{label_lifetime_node_id,
label.get_node_id ()});
}
- ResolveExpr::go (expr.get_loop_block ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_loop_block ().get (), expr.get_node_id ());
}
void visit (AST::BreakExpr &expr) override
@@ -340,7 +340,7 @@ public:
}
if (expr.has_break_expr ())
- ResolveExpr::go (expr.get_break_expr ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_break_expr ().get (), expr.get_node_id ());
}
void visit (AST::WhileLoopExpr &expr) override
@@ -370,8 +370,8 @@ public:
Definition{label_lifetime_node_id,
label.get_node_id ()});
}
- ResolveExpr::go (expr.get_predicate_expr ().get (), expr.get_node_id ());
- ResolveExpr::go (expr.get_loop_block ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_predicate_expr ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_loop_block ().get (), expr.get_node_id ());
}
void visit (AST::ContinueExpr &expr) override
@@ -402,17 +402,17 @@ public:
void visit (AST::BorrowExpr &expr) override
{
- ResolveExpr::go (expr.get_borrowed_expr ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_borrowed_expr ().get (), expr.get_node_id ());
}
void visit (AST::DereferenceExpr &expr) override
{
- ResolveExpr::go (expr.get_dereferenced_expr ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_dereferenced_expr ().get (), expr.get_node_id ());
}
void visit (AST::MatchExpr &expr) override
{
- ResolveExpr::go (expr.get_scrutinee_expr ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_scrutinee_expr ().get (), expr.get_node_id ());
for (auto &match_case : expr.get_match_cases ())
{
// each arm is in its own scope
@@ -427,7 +427,7 @@ public:
// resolve
AST::MatchArm &arm = match_case.get_arm ();
if (arm.has_match_arm_guard ())
- ResolveExpr::go (arm.get_guard_expr ().get (), expr.get_node_id ());
+ resolve_expr (arm.get_guard_expr ().get (), expr.get_node_id ());
// insert any possible new patterns
for (auto &pattern : arm.get_patterns ())
@@ -436,7 +436,7 @@ public:
}
// resolve the body
- ResolveExpr::go (match_case.get_expr ().get (), expr.get_node_id ());
+ resolve_expr (match_case.get_expr ().get (), expr.get_node_id ());
// done
resolver->get_name_scope ().pop ();
@@ -445,8 +445,21 @@ public:
}
}
+protected:
+ void resolve_expr (AST::Expr *e, NodeId parent)
+ {
+ ResolveExpr::go (e, parent, prefix, canonical_prefix);
+ }
+
private:
- ResolveExpr (NodeId parent) : ResolverBase (parent) {}
+ ResolveExpr (NodeId parent, const CanonicalPath &prefix,
+ const CanonicalPath &canonical_prefix)
+ : ResolverBase (parent), prefix (prefix),
+ canonical_prefix (canonical_prefix)
+ {}
+
+ const CanonicalPath &prefix;
+ const CanonicalPath &canonical_prefix;
};
} // namespace Resolver
diff --git a/gcc/rust/resolve/rust-ast-resolve-implitem.h b/gcc/rust/resolve/rust-ast-resolve-implitem.h
index 4bc14b9..074855e 100644
--- a/gcc/rust/resolve/rust-ast-resolve-implitem.h
+++ b/gcc/rust/resolve/rust-ast-resolve-implitem.h
@@ -45,8 +45,10 @@ public:
void visit (AST::TypeAlias &type) override
{
- auto path = prefix.append (
- CanonicalPath::new_seg (type.get_node_id (), type.get_new_type_name ()));
+ auto decl
+ = CanonicalPath::new_seg (type.get_node_id (), type.get_new_type_name ());
+ auto path = prefix.append (decl);
+
resolver->get_type_scope ().insert (
path, type.get_node_id (), type.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
@@ -58,8 +60,9 @@ public:
void visit (AST::ConstantItem &constant) override
{
- auto path
- = prefix.append (ResolveConstantItemToCanonicalPath::resolve (constant));
+ auto decl = ResolveConstantItemToCanonicalPath::resolve (constant);
+ auto path = prefix.append (decl);
+
resolver->get_name_scope ().insert (
path, constant.get_node_id (), constant.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
@@ -74,8 +77,9 @@ public:
void visit (AST::Function &function) override
{
- auto path
- = prefix.append (ResolveFunctionItemToCanonicalPath::resolve (function));
+ auto decl = ResolveFunctionItemToCanonicalPath::resolve (function);
+ auto path = prefix.append (decl);
+
resolver->get_name_scope ().insert (
path, function.get_node_id (), function.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
@@ -90,8 +94,9 @@ public:
void visit (AST::Method &method) override
{
- auto path
- = prefix.append (ResolveMethodItemToCanonicalPath::resolve (method));
+ auto decl = ResolveMethodItemToCanonicalPath::resolve (method);
+ auto path = prefix.append (decl);
+
resolver->get_name_scope ().insert (
path, method.get_node_id (), method.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
@@ -119,17 +124,19 @@ class ResolveTopLevelTraitItems : public ResolverBase
using Rust::Resolver::ResolverBase::visit;
public:
- static void go (AST::TraitItem *item,
- const CanonicalPath &prefix = CanonicalPath::create_empty ())
+ static void go (AST::TraitItem *item, const CanonicalPath &prefix,
+ const CanonicalPath &canonical_prefix)
{
- ResolveTopLevelTraitItems resolver (prefix);
+ ResolveTopLevelTraitItems resolver (prefix, canonical_prefix);
item->accept_vis (resolver);
};
void visit (AST::TraitItemFunc &function) override
{
- auto path = prefix.append (
- ResolveTraitItemFunctionToCanonicalPath::resolve (function));
+ auto decl = ResolveTraitItemFunctionToCanonicalPath::resolve (function);
+ auto path = prefix.append (decl);
+ auto cpath = canonical_prefix.append (decl);
+
resolver->get_name_scope ().insert (
path, function.get_node_id (), function.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
@@ -140,12 +147,17 @@ public:
resolver->insert_new_definition (function.get_node_id (),
Definition{function.get_node_id (),
function.get_node_id ()});
+
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ function.get_node_id (), cpath);
}
void visit (AST::TraitItemMethod &method) override
{
- auto path
- = prefix.append (ResolveTraitItemMethodToCanonicalPath::resolve (method));
+ auto decl = ResolveTraitItemMethodToCanonicalPath::resolve (method);
+ auto path = prefix.append (decl);
+ auto cpath = canonical_prefix.append (decl);
+
resolver->get_name_scope ().insert (
path, method.get_node_id (), method.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
@@ -156,12 +168,17 @@ public:
resolver->insert_new_definition (method.get_node_id (),
Definition{method.get_node_id (),
method.get_node_id ()});
+
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ method.get_node_id (), cpath);
}
void visit (AST::TraitItemConst &constant) override
{
- auto path = prefix.append (
- ResolveTraitItemConstToCanonicalPath::resolve (constant));
+ auto decl = ResolveTraitItemConstToCanonicalPath::resolve (constant);
+ auto path = prefix.append (decl);
+ auto cpath = canonical_prefix.append (decl);
+
resolver->get_name_scope ().insert (
path, constant.get_node_id (), constant.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
@@ -172,12 +189,17 @@ public:
resolver->insert_new_definition (constant.get_node_id (),
Definition{constant.get_node_id (),
constant.get_node_id ()});
+
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ constant.get_node_id (), cpath);
}
void visit (AST::TraitItemType &type) override
{
- auto path
- = prefix.append (ResolveTraitItemTypeToCanonicalPath::resolve (type));
+ auto decl = ResolveTraitItemTypeToCanonicalPath::resolve (type);
+ auto path = prefix.append (decl);
+ auto cpath = canonical_prefix.append (decl);
+
resolver->get_type_scope ().insert (
path, type.get_node_id (), type.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
@@ -185,14 +207,20 @@ public:
r.add_range (locus);
rust_error_at (r, "redefined multiple times");
});
+
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ type.get_node_id (), cpath);
}
private:
- ResolveTopLevelTraitItems (const CanonicalPath &prefix)
- : ResolverBase (UNKNOWN_NODEID), prefix (prefix)
+ ResolveTopLevelTraitItems (const CanonicalPath &prefix,
+ const CanonicalPath &canonical_prefix)
+ : ResolverBase (UNKNOWN_NODEID), prefix (prefix),
+ canonical_prefix (canonical_prefix)
{}
const CanonicalPath &prefix;
+ const CanonicalPath &canonical_prefix;
};
class ResolveToplevelExternItem : public ResolverBase
@@ -200,8 +228,7 @@ class ResolveToplevelExternItem : public ResolverBase
using Rust::Resolver::ResolverBase::visit;
public:
- static void go (AST::ExternalItem *item,
- const CanonicalPath &prefix = CanonicalPath::create_empty ())
+ static void go (AST::ExternalItem *item, const CanonicalPath &prefix)
{
ResolveToplevelExternItem resolver (prefix);
item->accept_vis (resolver);
@@ -209,9 +236,10 @@ public:
void visit (AST::ExternalFunctionItem &function) override
{
- auto path
- = prefix.append (CanonicalPath::new_seg (function.get_node_id (),
- function.get_identifier ()));
+ auto decl = CanonicalPath::new_seg (function.get_node_id (),
+ function.get_identifier ());
+ auto path = prefix.append (decl);
+
resolver->get_name_scope ().insert (
path, function.get_node_id (), function.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
@@ -226,8 +254,10 @@ public:
void visit (AST::ExternalStaticItem &item) override
{
- auto path = prefix.append (
- CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ()));
+ auto decl
+ = CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ());
+ auto path = prefix.append (decl);
+
resolver->get_name_scope ().insert (
path, item.get_node_id (), item.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.h b/gcc/rust/resolve/rust-ast-resolve-item.h
index 200c5ff..e428880 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.h
+++ b/gcc/rust/resolve/rust-ast-resolve-item.h
@@ -35,20 +35,33 @@ class ResolveTraitItems : public ResolverBase
using Rust::Resolver::ResolverBase::visit;
public:
- static void go (AST::TraitItem *item)
+ static void go (AST::TraitItem *item, const CanonicalPath &prefix,
+ const CanonicalPath &canonical_prefix)
{
- ResolveTraitItems resolver;
+ ResolveTraitItems resolver (prefix, canonical_prefix);
item->accept_vis (resolver);
};
void visit (AST::TraitItemType &type) override
{
+ auto decl = ResolveTraitItemTypeToCanonicalPath::resolve (type);
+ auto path = prefix.append (decl);
+ auto cpath = canonical_prefix.append (decl);
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ type.get_node_id (), cpath);
+
for (auto &bound : type.get_type_param_bounds ())
ResolveTypeBound::go (bound.get (), type.get_node_id ());
}
void visit (AST::TraitItemFunc &func) override
{
+ auto decl = ResolveTraitItemFunctionToCanonicalPath::resolve (func);
+ auto path = prefix.append (decl);
+ auto cpath = canonical_prefix.append (decl);
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ func.get_node_id (), cpath);
+
NodeId scope_node_id = func.get_node_id ();
resolver->get_name_scope ().push (scope_node_id);
resolver->get_type_scope ().push (scope_node_id);
@@ -86,7 +99,8 @@ public:
// trait items have an optional body
if (func.has_definition ())
- ResolveExpr::go (func.get_definition ().get (), func.get_node_id ());
+ ResolveExpr::go (func.get_definition ().get (), func.get_node_id (), path,
+ cpath);
resolver->get_name_scope ().pop ();
resolver->get_type_scope ().pop ();
@@ -95,6 +109,12 @@ public:
void visit (AST::TraitItemMethod &func) override
{
+ auto decl = ResolveTraitItemMethodToCanonicalPath::resolve (func);
+ auto path = prefix.append (decl);
+ auto cpath = canonical_prefix.append (decl);
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ func.get_node_id (), cpath);
+
NodeId scope_node_id = func.get_node_id ();
resolver->get_name_scope ().push (scope_node_id);
resolver->get_type_scope ().push (scope_node_id);
@@ -152,7 +172,8 @@ public:
// trait items have an optional body
if (func.has_definition ())
- ResolveExpr::go (func.get_definition ().get (), func.get_node_id ());
+ ResolveExpr::go (func.get_definition ().get (), func.get_node_id (), path,
+ cpath);
resolver->get_name_scope ().pop ();
resolver->get_type_scope ().pop ();
@@ -161,10 +182,17 @@ public:
void visit (AST::TraitItemConst &constant) override
{
+ auto decl = ResolveTraitItemConstToCanonicalPath::resolve (constant);
+ auto path = prefix.append (decl);
+ auto cpath = canonical_prefix.append (decl);
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ constant.get_node_id (), cpath);
+
ResolveType::go (constant.get_type ().get (), constant.get_node_id ());
if (constant.has_expr ())
- ResolveExpr::go (constant.get_expr ().get (), constant.get_node_id ());
+ ResolveExpr::go (constant.get_expr ().get (), constant.get_node_id (),
+ path, cpath);
// the mutability checker needs to verify for immutable decls the number
// of assignments are <1. This marks an implicit assignment
@@ -174,7 +202,14 @@ public:
}
private:
- ResolveTraitItems () : ResolverBase (UNKNOWN_NODEID) {}
+ ResolveTraitItems (const CanonicalPath &prefix,
+ const CanonicalPath &canonical_prefix)
+ : ResolverBase (UNKNOWN_NODEID), prefix (prefix),
+ canonical_prefix (canonical_prefix)
+ {}
+
+ const CanonicalPath &prefix;
+ const CanonicalPath &canonical_prefix;
};
class ResolveItem : public ResolverBase
@@ -182,14 +217,22 @@ class ResolveItem : public ResolverBase
public:
using Rust::Resolver::ResolverBase::visit;
- static void go (AST::Item *item)
+ static void go (AST::Item *item, const CanonicalPath &prefix,
+ const CanonicalPath &canonical_prefix)
{
- ResolveItem resolver;
+ ResolveItem resolver (prefix, canonical_prefix);
item->accept_vis (resolver);
};
void visit (AST::TypeAlias &alias) override
{
+ auto talias = CanonicalPath::new_seg (alias.get_node_id (),
+ alias.get_new_type_name ());
+ auto path = prefix.append (talias);
+ auto cpath = canonical_prefix.append (talias);
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ alias.get_node_id (), cpath);
+
NodeId scope_node_id = alias.get_node_id ();
resolver->get_type_scope ().push (scope_node_id);
@@ -209,6 +252,13 @@ public:
void visit (AST::Module &module) override
{
+ auto mod
+ = CanonicalPath::new_seg (module.get_node_id (), module.get_name ());
+ auto path = prefix.append (mod);
+ auto cpath = canonical_prefix.append (mod);
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ module.get_node_id (), cpath);
+
NodeId scope_node_id = module.get_node_id ();
resolver->get_name_scope ().push (scope_node_id);
resolver->get_type_scope ().push (scope_node_id);
@@ -218,10 +268,10 @@ public:
resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
for (auto &item : module.get_items ())
- ResolveTopLevel::go (item.get ());
+ ResolveTopLevel::go (item.get (), CanonicalPath::create_empty (), cpath);
for (auto &item : module.get_items ())
- ResolveItem::go (item.get ());
+ ResolveItem::go (item.get (), path, cpath);
resolver->get_name_scope ().pop ();
resolver->get_type_scope ().pop ();
@@ -230,6 +280,13 @@ public:
void visit (AST::TupleStruct &struct_decl) override
{
+ auto decl = CanonicalPath::new_seg (struct_decl.get_node_id (),
+ struct_decl.get_identifier ());
+ auto path = prefix.append (decl);
+ auto cpath = canonical_prefix.append (decl);
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ struct_decl.get_node_id (), cpath);
+
NodeId scope_node_id = struct_decl.get_node_id ();
resolver->get_type_scope ().push (scope_node_id);
@@ -254,6 +311,13 @@ public:
void visit (AST::Enum &enum_decl) override
{
+ auto decl = CanonicalPath::new_seg (enum_decl.get_node_id (),
+ enum_decl.get_identifier ());
+ auto path = prefix.append (decl);
+ auto cpath = canonical_prefix.append (decl);
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ enum_decl.get_node_id (), cpath);
+
NodeId scope_node_id = enum_decl.get_node_id ();
resolver->get_type_scope ().push (scope_node_id);
@@ -270,7 +334,7 @@ public:
/* The actual fields are inside the variants. */
for (auto &variant : enum_decl.get_variants ())
- ResolveItem::go (variant.get ());
+ ResolveItem::go (variant.get (), path, cpath);
resolver->get_type_scope ().pop ();
}
@@ -279,20 +343,50 @@ public:
void visit (AST::EnumItemTuple &item) override
{
+ auto decl
+ = CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ());
+ auto path = prefix.append (decl);
+ auto cpath = canonical_prefix.append (decl);
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ item.get_node_id (), cpath);
+
for (auto &field : item.get_tuple_fields ())
ResolveType::go (field.get_field_type ().get (), item.get_node_id ());
}
void visit (AST::EnumItemStruct &item) override
{
+ auto decl
+ = CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ());
+ auto path = prefix.append (decl);
+ auto cpath = canonical_prefix.append (decl);
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ item.get_node_id (), cpath);
+
for (auto &field : item.get_struct_fields ())
ResolveType::go (field.get_field_type ().get (), item.get_node_id ());
}
- /* EnumItemDiscriminant doesn't need to be handled, no fields. */
+ void visit (AST::EnumItemDiscriminant &item) override
+ {
+ auto decl
+ = CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ());
+ auto path = prefix.append (decl);
+ auto cpath = canonical_prefix.append (decl);
+
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ item.get_node_id (), cpath);
+ }
void visit (AST::StructStruct &struct_decl) override
{
+ auto decl = CanonicalPath::new_seg (struct_decl.get_node_id (),
+ struct_decl.get_identifier ());
+ auto path = prefix.append (decl);
+ auto cpath = canonical_prefix.append (decl);
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ struct_decl.get_node_id (), cpath);
+
NodeId scope_node_id = struct_decl.get_node_id ();
resolver->get_type_scope ().push (scope_node_id);
@@ -317,6 +411,13 @@ public:
void visit (AST::Union &union_decl) override
{
+ auto decl = CanonicalPath::new_seg (union_decl.get_node_id (),
+ union_decl.get_identifier ());
+ auto path = prefix.append (decl);
+ auto cpath = canonical_prefix.append (decl);
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ union_decl.get_node_id (), cpath);
+
NodeId scope_node_id = union_decl.get_node_id ();
resolver->get_type_scope ().push (scope_node_id);
@@ -340,8 +441,15 @@ public:
void visit (AST::StaticItem &var) override
{
+ auto decl
+ = CanonicalPath::new_seg (var.get_node_id (), var.get_identifier ());
+ auto path = prefix.append (decl);
+ auto cpath = canonical_prefix.append (decl);
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ var.get_node_id (), cpath);
+
ResolveType::go (var.get_type ().get (), var.get_node_id ());
- ResolveExpr::go (var.get_expr ().get (), var.get_node_id ());
+ ResolveExpr::go (var.get_expr ().get (), var.get_node_id (), path, cpath);
// the mutability checker needs to verify for immutable decls the number
// of assignments are <1. This marks an implicit assignment
@@ -350,8 +458,15 @@ public:
void visit (AST::ConstantItem &constant) override
{
+ auto decl = ResolveConstantItemToCanonicalPath::resolve (constant);
+ auto path = prefix.append (decl);
+ auto cpath = canonical_prefix.append (decl);
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ constant.get_node_id (), cpath);
+
ResolveType::go (constant.get_type ().get (), constant.get_node_id ());
- ResolveExpr::go (constant.get_expr ().get (), constant.get_node_id ());
+ ResolveExpr::go (constant.get_expr ().get (), constant.get_node_id (), path,
+ cpath);
// the mutability checker needs to verify for immutable decls the number
// of assignments are <1. This marks an implicit assignment
@@ -365,6 +480,12 @@ public:
if (function.is_marked_for_strip ())
return;
+ auto decl = ResolveFunctionItemToCanonicalPath::resolve (function);
+ auto path = prefix.append (decl);
+ auto cpath = canonical_prefix.append (decl);
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ function.get_node_id (), cpath);
+
NodeId scope_node_id = function.get_node_id ();
resolver->get_name_scope ().push (scope_node_id);
resolver->get_type_scope ().push (scope_node_id);
@@ -402,8 +523,8 @@ public:
}
// resolve the function body
- ResolveExpr::go (function.get_definition ().get (),
- function.get_node_id ());
+ ResolveExpr::go (function.get_definition ().get (), function.get_node_id (),
+ path, cpath);
resolver->get_name_scope ().pop ();
resolver->get_type_scope ().pop ();
@@ -430,10 +551,15 @@ public:
if (impl_block.has_where_clause ())
ResolveWhereClause::Resolve (impl_block.get_where_clause ());
+ // FIXME this needs to be protected behind nominal type-checks see:
+ // rustc --explain E0118
+
+ CanonicalPath self_cpath = CanonicalPath::create_empty ();
bool canonicalize_type_with_generics = false;
- NodeId resolved_node = ResolveType::go (impl_block.get_type ().get (),
- impl_block.get_node_id (),
- canonicalize_type_with_generics);
+ NodeId resolved_node
+ = ResolveType::go (impl_block.get_type ().get (),
+ impl_block.get_node_id (),
+ canonicalize_type_with_generics, &self_cpath);
if (resolved_node == UNKNOWN_NODEID)
{
resolver->get_type_scope ().pop ();
@@ -441,6 +567,31 @@ public:
return;
}
+ // Setup paths
+ bool canonicalize_type_args = !impl_block.has_generics ();
+ bool type_resolve_generic_args = false;
+
+ CanonicalPath impl_type
+ = ResolveTypeToCanonicalPath::resolve (*impl_block.get_type ().get (),
+ canonicalize_type_args,
+ type_resolve_generic_args);
+ CanonicalPath impl_prefix = prefix.append (impl_type);
+
+ // see https://godbolt.org/z/a3vMbsT6W
+ CanonicalPath cpath = CanonicalPath::create_empty ();
+ if (canonical_prefix.size () > 1)
+ {
+ std::string seg_buf = "<impl " + self_cpath.get () + ">";
+ CanonicalPath seg
+ = CanonicalPath::new_seg (impl_block.get_node_id (), seg_buf);
+ cpath = canonical_prefix.append (seg);
+ }
+ else
+ {
+ cpath = canonical_prefix.append (self_cpath);
+ }
+ // done setup paths
+
auto Self
= CanonicalPath::get_big_self (impl_block.get_type ()->get_node_id ());
@@ -450,7 +601,7 @@ public:
for (auto &impl_item : impl_block.get_impl_items ())
{
- resolve_impl_item (impl_item.get ());
+ resolve_impl_item (impl_item.get (), impl_prefix, cpath);
}
resolver->get_type_scope ().peek ()->clear_name (
@@ -462,6 +613,12 @@ public:
void visit (AST::Method &method) override
{
+ auto decl = ResolveMethodItemToCanonicalPath::resolve (method);
+ auto path = prefix.append (decl);
+ auto cpath = canonical_prefix.append (decl);
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ method.get_node_id (), cpath);
+
NodeId scope_node_id = method.get_node_id ();
resolver->get_name_scope ().push (scope_node_id);
resolver->get_type_scope ().push (scope_node_id);
@@ -522,7 +679,8 @@ public:
ResolveWhereClause::Resolve (method.get_where_clause ());
// resolve the function body
- ResolveExpr::go (method.get_definition ().get (), method.get_node_id ());
+ ResolveExpr::go (method.get_definition ().get (), method.get_node_id (),
+ path, cpath);
resolver->get_name_scope ().pop ();
resolver->get_type_scope ().pop ();
@@ -549,11 +707,13 @@ public:
if (impl_block.has_where_clause ())
ResolveWhereClause::Resolve (impl_block.get_where_clause ());
+ CanonicalPath canonical_trait_type = CanonicalPath::create_empty ();
bool canonicalize_type_with_generics = false;
NodeId trait_resolved_node
= ResolveType::go (&impl_block.get_trait_path (),
impl_block.get_node_id (),
- canonicalize_type_with_generics);
+ canonicalize_type_with_generics,
+ &canonical_trait_type);
if (trait_resolved_node == UNKNOWN_NODEID)
{
resolver->get_type_scope ().pop ();
@@ -561,10 +721,11 @@ public:
return;
}
+ CanonicalPath canonical_impl_type = CanonicalPath::create_empty ();
NodeId type_resolved_node
= ResolveType::go (impl_block.get_type ().get (),
impl_block.get_node_id (),
- canonicalize_type_with_generics);
+ canonicalize_type_with_generics, &canonical_impl_type);
if (type_resolved_node == UNKNOWN_NODEID)
{
resolver->get_type_scope ().pop ();
@@ -572,6 +733,46 @@ public:
return;
}
+ // setup paths
+ bool canonicalize_type_args = !impl_block.has_generics ();
+ bool type_resolve_generic_args = false;
+
+ CanonicalPath impl_type_seg
+ = ResolveTypeToCanonicalPath::resolve (*impl_block.get_type ().get (),
+ canonicalize_type_args,
+ type_resolve_generic_args);
+ CanonicalPath trait_type_seg
+ = ResolveTypeToCanonicalPath::resolve (impl_block.get_trait_path (),
+ canonicalize_type_args,
+ type_resolve_generic_args);
+
+ CanonicalPath projection
+ = TraitImplProjection::resolve (impl_block.get_node_id (), trait_type_seg,
+ impl_type_seg);
+ CanonicalPath impl_prefix = prefix.append (projection);
+
+ // setup canonical-path
+ CanonicalPath canonical_projection
+ = TraitImplProjection::resolve (impl_block.get_node_id (),
+ canonical_trait_type,
+ canonical_impl_type);
+ CanonicalPath cpath = CanonicalPath::create_empty ();
+ if (canonical_prefix.size () > 1)
+ {
+ std::string projection_str = canonical_projection.get ();
+ std::string seg_buf
+ = "<impl " + projection_str.substr (1, projection_str.size () - 2)
+ + ">";
+ CanonicalPath seg
+ = CanonicalPath::new_seg (impl_block.get_node_id (), seg_buf);
+ cpath = canonical_prefix.append (seg);
+ }
+ else
+ {
+ cpath = canonical_prefix.append (canonical_projection);
+ }
+ // DONE setup canonical-path
+
auto Self
= CanonicalPath::get_big_self (impl_block.get_type ()->get_node_id ());
@@ -581,7 +782,7 @@ public:
for (auto &impl_item : impl_block.get_impl_items ())
{
- resolve_impl_item (impl_item.get ());
+ resolve_impl_item (impl_item.get (), impl_prefix, cpath);
}
resolver->get_type_scope ().peek ()->clear_name (
@@ -625,9 +826,14 @@ public:
if (trait.has_where_clause ())
ResolveWhereClause::Resolve (trait.get_where_clause ());
+ // resolve the paths
+ CanonicalPath path = CanonicalPath::create_empty ();
+ CanonicalPath cpath = CanonicalPath::create_empty ();
+ //
+
for (auto &item : trait.get_trait_items ())
{
- ResolveTraitItems::go (item.get ());
+ ResolveTraitItems::go (item.get (), path, cpath);
}
resolver->get_type_scope ().pop ();
@@ -643,11 +849,21 @@ public:
}
protected:
- void resolve_impl_item (AST::TraitImplItem *item);
- void resolve_impl_item (AST::InherentImplItem *item);
+ void resolve_impl_item (AST::TraitImplItem *item, const CanonicalPath &prefix,
+ const CanonicalPath &canonical_prefix);
+ void resolve_impl_item (AST::InherentImplItem *item,
+ const CanonicalPath &prefix,
+ const CanonicalPath &canonical_prefix);
void resolve_extern_item (AST::ExternalItem *item);
- ResolveItem () : ResolverBase (UNKNOWN_NODEID) {}
+ ResolveItem (const CanonicalPath &prefix,
+ const CanonicalPath &canonical_prefix)
+ : ResolverBase (UNKNOWN_NODEID), prefix (prefix),
+ canonical_prefix (canonical_prefix)
+ {}
+
+ const CanonicalPath &prefix;
+ const CanonicalPath &canonical_prefix;
};
class ResolveImplItems : public ResolveItem
@@ -655,15 +871,17 @@ class ResolveImplItems : public ResolveItem
using Rust::Resolver::ResolveItem::visit;
public:
- static void go (AST::InherentImplItem *item)
+ static void go (AST::InherentImplItem *item, const CanonicalPath &prefix,
+ const CanonicalPath &canonical_prefix)
{
- ResolveImplItems resolver;
+ ResolveImplItems resolver (prefix, canonical_prefix);
item->accept_vis (resolver);
};
- static void go (AST::TraitImplItem *item)
+ static void go (AST::TraitImplItem *item, const CanonicalPath &prefix,
+ const CanonicalPath &canonical_prefix)
{
- ResolveImplItems resolver;
+ ResolveImplItems resolver (prefix, canonical_prefix);
item->accept_vis (resolver);
};
@@ -677,7 +895,10 @@ public:
}
private:
- ResolveImplItems () : ResolveItem () {}
+ ResolveImplItems (const CanonicalPath &prefix,
+ const CanonicalPath &canonical_prefix)
+ : ResolveItem (prefix, canonical_prefix)
+ {}
};
class ResolveExternItem : public ResolverBase
diff --git a/gcc/rust/resolve/rust-ast-resolve-pattern.cc b/gcc/rust/resolve/rust-ast-resolve-pattern.cc
index 8a4a634..0c7c8f3 100644
--- a/gcc/rust/resolve/rust-ast-resolve-pattern.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-pattern.cc
@@ -25,13 +25,13 @@ namespace Resolver {
void
PatternDeclaration::visit (AST::PathInExpression &pattern)
{
- ResolveExpr::go (&pattern, parent);
+ ResolvePath::go (&pattern, parent);
}
void
PatternDeclaration::visit (AST::TupleStructPattern &pattern)
{
- ResolveExpr::go (&pattern.get_path (), parent);
+ ResolvePath::go (&pattern.get_path (), parent);
std::unique_ptr<AST::TupleStructItems> &items = pattern.get_items ();
switch (items->get_item_type ())
@@ -59,7 +59,7 @@ PatternDeclaration::visit (AST::TupleStructPattern &pattern)
void
PatternDeclaration::visit (AST::StructPattern &pattern)
{
- ResolveExpr::go (&pattern.get_path (), parent);
+ ResolvePath::go (&pattern.get_path (), parent);
auto &struct_pattern_elems = pattern.get_struct_pattern_elems ();
for (auto &field : struct_pattern_elems.get_struct_pattern_fields ())
diff --git a/gcc/rust/resolve/rust-ast-resolve-stmt.h b/gcc/rust/resolve/rust-ast-resolve-stmt.h
index c84d842..308de14 100644
--- a/gcc/rust/resolve/rust-ast-resolve-stmt.h
+++ b/gcc/rust/resolve/rust-ast-resolve-stmt.h
@@ -33,27 +33,34 @@ class ResolveStmt : public ResolverBase
using Rust::Resolver::ResolverBase::visit;
public:
- static void go (AST::Stmt *stmt, NodeId parent,
- const CanonicalPath &enum_prefix
- = CanonicalPath::create_empty ())
+ static void go (AST::Stmt *stmt, NodeId parent, const CanonicalPath &prefix,
+ const CanonicalPath &canonical_prefix,
+ const CanonicalPath &enum_prefix)
{
- ResolveStmt resolver (parent, enum_prefix);
+ ResolveStmt resolver (parent, prefix, canonical_prefix, enum_prefix);
stmt->accept_vis (resolver);
};
void visit (AST::ExprStmtWithBlock &stmt) override
{
- ResolveExpr::go (stmt.get_expr ().get (), stmt.get_node_id ());
+ ResolveExpr::go (stmt.get_expr ().get (), stmt.get_node_id (), prefix,
+ canonical_prefix);
}
void visit (AST::ExprStmtWithoutBlock &stmt) override
{
- ResolveExpr::go (stmt.get_expr ().get (), stmt.get_node_id ());
+ ResolveExpr::go (stmt.get_expr ().get (), stmt.get_node_id (), prefix,
+ canonical_prefix);
}
void visit (AST::ConstantItem &constant) override
{
- auto path = ResolveConstantItemToCanonicalPath::resolve (constant);
+ auto decl = ResolveConstantItemToCanonicalPath::resolve (constant);
+ auto path = decl; // this ensures we have the correct relative resolution
+ auto cpath = canonical_prefix.append (decl);
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ constant.get_node_id (), cpath);
+
resolver->get_name_scope ().insert (
path, constant.get_node_id (), constant.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
@@ -66,7 +73,8 @@ public:
constant.get_node_id ()});
ResolveType::go (constant.get_type ().get (), constant.get_node_id ());
- ResolveExpr::go (constant.get_expr ().get (), constant.get_node_id ());
+ ResolveExpr::go (constant.get_expr ().get (), constant.get_node_id (),
+ prefix, canonical_prefix);
// the mutability checker needs to verify for immutable decls the number
// of assignments are <1. This marks an implicit assignment
@@ -79,7 +87,8 @@ public:
{
if (stmt.has_init_expr ())
{
- ResolveExpr::go (stmt.get_init_expr ().get (), stmt.get_node_id ());
+ ResolveExpr::go (stmt.get_init_expr ().get (), stmt.get_node_id (),
+ prefix, canonical_prefix);
// mark the assignment
resolver->mark_assignment_to_decl (
@@ -93,8 +102,13 @@ public:
void visit (AST::TupleStruct &struct_decl) override
{
- auto path = CanonicalPath::new_seg (struct_decl.get_node_id (),
+ auto decl = CanonicalPath::new_seg (struct_decl.get_node_id (),
struct_decl.get_identifier ());
+ auto path = decl; // this ensures we have the correct relative resolution
+ auto cpath = canonical_prefix.append (decl);
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ struct_decl.get_node_id (), cpath);
+
resolver->get_type_scope ().insert (
path, struct_decl.get_node_id (), struct_decl.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
@@ -124,10 +138,15 @@ public:
void visit (AST::Enum &enum_decl) override
{
- auto enum_path = CanonicalPath::new_seg (enum_decl.get_node_id (),
- enum_decl.get_identifier ());
+ auto decl = CanonicalPath::new_seg (enum_decl.get_node_id (),
+ enum_decl.get_identifier ());
+ auto path = decl; // this ensures we have the correct relative resolution
+ auto cpath = canonical_prefix.append (decl);
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ enum_decl.get_node_id (), cpath);
+
resolver->get_type_scope ().insert (
- enum_path, enum_decl.get_node_id (), enum_decl.get_locus (), false,
+ path, enum_decl.get_node_id (), enum_decl.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
RichLocation r (enum_decl.get_locus ());
r.add_range (locus);
@@ -146,15 +165,20 @@ public:
}
for (auto &variant : enum_decl.get_variants ())
- ResolveStmt::go (variant.get (), parent, enum_path);
+ ResolveStmt::go (variant.get (), parent, path, canonical_prefix, path);
resolver->get_type_scope ().pop ();
}
void visit (AST::EnumItem &item) override
{
- auto path = enum_prefix.append (
+ auto decl = enum_prefix.append (
CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ()));
+ auto path = decl; // this ensures we have the correct relative resolution
+ auto cpath = canonical_prefix.append (decl);
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ item.get_node_id (), cpath);
+
resolver->get_type_scope ().insert (
path, item.get_node_id (), item.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
@@ -168,8 +192,13 @@ public:
void visit (AST::EnumItemTuple &item) override
{
- auto path = enum_prefix.append (
+ auto decl = enum_prefix.append (
CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ()));
+ auto path = decl; // this ensures we have the correct relative resolution
+ auto cpath = canonical_prefix.append (decl);
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ item.get_node_id (), cpath);
+
resolver->get_type_scope ().insert (
path, item.get_node_id (), item.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
@@ -184,8 +213,13 @@ public:
void visit (AST::EnumItemStruct &item) override
{
- auto path = enum_prefix.append (
+ auto decl = enum_prefix.append (
CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ()));
+ auto path = decl; // this ensures we have the correct relative resolution
+ auto cpath = canonical_prefix.append (decl);
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ item.get_node_id (), cpath);
+
resolver->get_type_scope ().insert (
path, item.get_node_id (), item.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
@@ -200,8 +234,13 @@ public:
void visit (AST::EnumItemDiscriminant &item) override
{
- auto path = enum_prefix.append (
+ auto decl = enum_prefix.append (
CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ()));
+ auto path = decl; // this ensures we have the correct relative resolution
+ auto cpath = canonical_prefix.append (decl);
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ item.get_node_id (), cpath);
+
resolver->get_type_scope ().insert (
path, item.get_node_id (), item.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
@@ -215,8 +254,13 @@ public:
void visit (AST::StructStruct &struct_decl) override
{
- auto path = CanonicalPath::new_seg (struct_decl.get_node_id (),
+ auto decl = CanonicalPath::new_seg (struct_decl.get_node_id (),
struct_decl.get_identifier ());
+ auto path = decl; // this ensures we have the correct relative resolution
+ auto cpath = canonical_prefix.append (decl);
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ struct_decl.get_node_id (), cpath);
+
resolver->get_type_scope ().insert (
path, struct_decl.get_node_id (), struct_decl.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
@@ -246,8 +290,13 @@ public:
void visit (AST::Union &union_decl) override
{
- auto path = CanonicalPath::new_seg (union_decl.get_node_id (),
+ auto decl = CanonicalPath::new_seg (union_decl.get_node_id (),
union_decl.get_identifier ());
+ auto path = decl; // this ensures we have the correct relative resolution
+ auto cpath = canonical_prefix.append (decl);
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ union_decl.get_node_id (), cpath);
+
resolver->get_type_scope ().insert (
path, union_decl.get_node_id (), union_decl.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
@@ -276,7 +325,12 @@ public:
void visit (AST::Function &function) override
{
- auto path = ResolveFunctionItemToCanonicalPath::resolve (function);
+ auto decl = ResolveFunctionItemToCanonicalPath::resolve (function);
+ auto path = decl; // this ensures we have the correct relative resolution
+ auto cpath = canonical_prefix.append (decl);
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ function.get_node_id (), cpath);
+
resolver->get_name_scope ().insert (
path, function.get_node_id (), function.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
@@ -321,8 +375,8 @@ public:
}
// resolve the function body
- ResolveExpr::go (function.get_definition ().get (),
- function.get_node_id ());
+ ResolveExpr::go (function.get_definition ().get (), function.get_node_id (),
+ path, cpath);
resolver->get_name_scope ().pop ();
resolver->get_type_scope ().pop ();
@@ -330,10 +384,16 @@ public:
}
private:
- ResolveStmt (NodeId parent, const CanonicalPath &enum_prefix)
- : ResolverBase (parent), enum_prefix (enum_prefix)
+ ResolveStmt (NodeId parent, const CanonicalPath &prefix,
+ const CanonicalPath &canonical_prefix,
+ const CanonicalPath &enum_prefix)
+ : ResolverBase (parent), prefix (prefix),
+ canonical_prefix (canonical_prefix), enum_prefix (enum_prefix)
{}
+ const CanonicalPath &prefix;
+ const CanonicalPath &canonical_prefix;
+
/* item declaration statements are not given a canonical path, but enum items
* (variants) do inherit the enum path/identifier name. */
const CanonicalPath &enum_prefix;
diff --git a/gcc/rust/resolve/rust-ast-resolve-struct-expr-field.h b/gcc/rust/resolve/rust-ast-resolve-struct-expr-field.h
index 1923d9e..b2c30a9 100644
--- a/gcc/rust/resolve/rust-ast-resolve-struct-expr-field.h
+++ b/gcc/rust/resolve/rust-ast-resolve-struct-expr-field.h
@@ -32,9 +32,11 @@ class ResolveStructExprField : public ResolverBase
using Rust::Resolver::ResolverBase::visit;
public:
- static void go (AST::StructExprField *field, NodeId parent)
+ static void go (AST::StructExprField *field, NodeId parent,
+ const CanonicalPath &prefix,
+ const CanonicalPath &canonical_prefix)
{
- ResolveStructExprField resolver (parent);
+ ResolveStructExprField resolver (parent, prefix, canonical_prefix);
field->accept_vis (resolver);
}
@@ -47,7 +49,14 @@ public:
void visit (AST::StructExprFieldIdentifier &field) override;
private:
- ResolveStructExprField (NodeId parent) : ResolverBase (parent) {}
+ ResolveStructExprField (NodeId parent, const CanonicalPath &prefix,
+ const CanonicalPath &canonical_prefix)
+ : ResolverBase (parent), prefix (prefix),
+ canonical_prefix (canonical_prefix)
+ {}
+
+ const CanonicalPath &prefix;
+ const CanonicalPath &canonical_prefix;
};
} // namespace Resolver
diff --git a/gcc/rust/resolve/rust-ast-resolve-toplevel.h b/gcc/rust/resolve/rust-ast-resolve-toplevel.h
index 4993649..56962f6 100644
--- a/gcc/rust/resolve/rust-ast-resolve-toplevel.h
+++ b/gcc/rust/resolve/rust-ast-resolve-toplevel.h
@@ -33,17 +33,20 @@ class ResolveTopLevel : public ResolverBase
using Rust::Resolver::ResolverBase::visit;
public:
- static void go (AST::Item *item,
- const CanonicalPath &prefix = CanonicalPath::create_empty ())
+ static void go (AST::Item *item, const CanonicalPath &prefix,
+ const CanonicalPath &canonical_prefix)
{
- ResolveTopLevel resolver (prefix);
+ ResolveTopLevel resolver (prefix, canonical_prefix);
item->accept_vis (resolver);
};
void visit (AST::Module &module) override
{
- auto path = prefix.append (
- CanonicalPath::new_seg (module.get_node_id (), module.get_name ()));
+ auto mod
+ = CanonicalPath::new_seg (module.get_node_id (), module.get_name ());
+ auto path = prefix.append (mod);
+ auto cpath = canonical_prefix.append (mod);
+
resolver->get_name_scope ().insert (
path, module.get_node_id (), module.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
@@ -57,14 +60,19 @@ public:
module.get_node_id ()});
for (auto &item : module.get_items ())
- ResolveTopLevel::go (item.get (), path);
+ ResolveTopLevel::go (item.get (), path, cpath);
+
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ module.get_node_id (), cpath);
}
void visit (AST::TypeAlias &alias) override
{
- auto path
- = prefix.append (CanonicalPath::new_seg (alias.get_node_id (),
- alias.get_new_type_name ()));
+ auto talias = CanonicalPath::new_seg (alias.get_node_id (),
+ alias.get_new_type_name ());
+ auto path = prefix.append (talias);
+ auto cpath = canonical_prefix.append (talias);
+
resolver->get_type_scope ().insert (
path, alias.get_node_id (), alias.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
@@ -72,13 +80,18 @@ public:
r.add_range (locus);
rust_error_at (r, "redefined multiple times");
});
+
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ alias.get_node_id (), cpath);
}
void visit (AST::TupleStruct &struct_decl) override
{
- auto path
- = prefix.append (CanonicalPath::new_seg (struct_decl.get_node_id (),
- struct_decl.get_identifier ()));
+ auto decl = CanonicalPath::new_seg (struct_decl.get_node_id (),
+ struct_decl.get_identifier ());
+ auto path = prefix.append (decl);
+ auto cpath = canonical_prefix.append (decl);
+
resolver->get_type_scope ().insert (
path, struct_decl.get_node_id (), struct_decl.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
@@ -86,13 +99,18 @@ public:
r.add_range (locus);
rust_error_at (r, "redefined multiple times");
});
+
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ struct_decl.get_node_id (), cpath);
}
void visit (AST::Enum &enum_decl) override
{
- auto path
- = prefix.append (CanonicalPath::new_seg (enum_decl.get_node_id (),
- enum_decl.get_identifier ()));
+ auto decl = CanonicalPath::new_seg (enum_decl.get_node_id (),
+ enum_decl.get_identifier ());
+ auto path = prefix.append (decl);
+ auto cpath = canonical_prefix.append (decl);
+
resolver->get_type_scope ().insert (
path, enum_decl.get_node_id (), enum_decl.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
@@ -102,13 +120,19 @@ public:
});
for (auto &variant : enum_decl.get_variants ())
- ResolveTopLevel::go (variant.get (), path);
+ ResolveTopLevel::go (variant.get (), path, cpath);
+
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ enum_decl.get_node_id (), cpath);
}
void visit (AST::EnumItem &item) override
{
- auto path = prefix.append (
- CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ()));
+ auto decl
+ = CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ());
+ auto path = prefix.append (decl);
+ auto cpath = canonical_prefix.append (decl);
+
resolver->get_type_scope ().insert (
path, item.get_node_id (), item.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
@@ -116,12 +140,18 @@ public:
r.add_range (locus);
rust_error_at (r, "redefined multiple times");
});
+
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ item.get_node_id (), cpath);
}
void visit (AST::EnumItemTuple &item) override
{
- auto path = prefix.append (
- CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ()));
+ auto decl
+ = CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ());
+ auto path = prefix.append (decl);
+ auto cpath = canonical_prefix.append (decl);
+
resolver->get_type_scope ().insert (
path, item.get_node_id (), item.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
@@ -129,12 +159,18 @@ public:
r.add_range (locus);
rust_error_at (r, "redefined multiple times");
});
+
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ item.get_node_id (), cpath);
}
void visit (AST::EnumItemStruct &item) override
{
- auto path = prefix.append (
- CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ()));
+ auto decl
+ = CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ());
+ auto path = prefix.append (decl);
+ auto cpath = canonical_prefix.append (decl);
+
resolver->get_type_scope ().insert (
path, item.get_node_id (), item.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
@@ -142,12 +178,18 @@ public:
r.add_range (locus);
rust_error_at (r, "redefined multiple times");
});
+
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ item.get_node_id (), cpath);
}
void visit (AST::EnumItemDiscriminant &item) override
{
- auto path = prefix.append (
- CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ()));
+ auto decl
+ = CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ());
+ auto path = prefix.append (decl);
+ auto cpath = canonical_prefix.append (decl);
+
resolver->get_type_scope ().insert (
path, item.get_node_id (), item.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
@@ -155,13 +197,18 @@ public:
r.add_range (locus);
rust_error_at (r, "redefined multiple times");
});
+
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ item.get_node_id (), cpath);
}
void visit (AST::StructStruct &struct_decl) override
{
- auto path
- = prefix.append (CanonicalPath::new_seg (struct_decl.get_node_id (),
- struct_decl.get_identifier ()));
+ auto decl = CanonicalPath::new_seg (struct_decl.get_node_id (),
+ struct_decl.get_identifier ());
+ auto path = prefix.append (decl);
+ auto cpath = canonical_prefix.append (decl);
+
resolver->get_type_scope ().insert (
path, struct_decl.get_node_id (), struct_decl.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
@@ -169,13 +216,18 @@ public:
r.add_range (locus);
rust_error_at (r, "redefined multiple times");
});
+
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ struct_decl.get_node_id (), cpath);
}
void visit (AST::Union &union_decl) override
{
- auto path
- = prefix.append (CanonicalPath::new_seg (union_decl.get_node_id (),
- union_decl.get_identifier ()));
+ auto decl = CanonicalPath::new_seg (union_decl.get_node_id (),
+ union_decl.get_identifier ());
+ auto path = prefix.append (decl);
+ auto cpath = canonical_prefix.append (decl);
+
resolver->get_type_scope ().insert (
path, union_decl.get_node_id (), union_decl.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
@@ -183,12 +235,18 @@ public:
r.add_range (locus);
rust_error_at (r, "redefined multiple times");
});
+
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ union_decl.get_node_id (), cpath);
}
void visit (AST::StaticItem &var) override
{
- auto path = prefix.append (
- CanonicalPath::new_seg (var.get_node_id (), var.get_identifier ()));
+ auto decl
+ = CanonicalPath::new_seg (var.get_node_id (), var.get_identifier ());
+ auto path = prefix.append (decl);
+ auto cpath = canonical_prefix.append (decl);
+
resolver->get_name_scope ().insert (
path, var.get_node_id (), var.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
@@ -200,12 +258,17 @@ public:
Definition{var.get_node_id (),
var.get_node_id ()});
resolver->mark_decl_mutability (var.get_node_id (), var.is_mutable ());
+
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ var.get_node_id (), cpath);
}
void visit (AST::ConstantItem &constant) override
{
- auto path
- = prefix.append (ResolveConstantItemToCanonicalPath::resolve (constant));
+ auto decl = ResolveConstantItemToCanonicalPath::resolve (constant);
+ auto path = prefix.append (decl);
+ auto cpath = canonical_prefix.append (decl);
+
resolver->get_name_scope ().insert (
path, constant.get_node_id (), constant.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
@@ -216,6 +279,9 @@ public:
resolver->insert_new_definition (constant.get_node_id (),
Definition{constant.get_node_id (),
constant.get_node_id ()});
+
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ constant.get_node_id (), cpath);
}
void visit (AST::Function &function) override
@@ -223,8 +289,10 @@ public:
if (function.is_marked_for_strip ())
return;
- auto path
- = prefix.append (ResolveFunctionItemToCanonicalPath::resolve (function));
+ auto decl = ResolveFunctionItemToCanonicalPath::resolve (function);
+ auto path = prefix.append (decl);
+ auto cpath = canonical_prefix.append (decl);
+
resolver->get_name_scope ().insert (
path, function.get_node_id (), function.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
@@ -243,12 +311,16 @@ public:
resolver->insert_resolved_name (function.get_node_id (),
function.get_node_id ());
}
+
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ function.get_node_id (), cpath);
}
void visit (AST::InherentImpl &impl_block) override
{
bool canonicalize_type_args = !impl_block.has_generics ();
bool type_resolve_generic_args = false;
+
CanonicalPath impl_type
= ResolveTypeToCanonicalPath::resolve (*impl_block.get_type ().get (),
canonicalize_type_args,
@@ -257,6 +329,8 @@ public:
for (auto &impl_item : impl_block.get_impl_items ())
ResolveToplevelImplItem::go (impl_item.get (), impl_prefix);
+
+ // we cannot resolve canonical paths here until later on
}
void visit (AST::TraitImpl &impl_block) override
@@ -293,12 +367,17 @@ public:
for (auto &impl_item : impl_block.get_impl_items ())
ResolveToplevelImplItem::go (impl_item.get (), impl_prefix);
+
+ // we cannot resolve canonical paths here until later on
}
void visit (AST::Trait &trait) override
{
- CanonicalPath path = prefix.append (
- CanonicalPath::new_seg (trait.get_node_id (), trait.get_identifier ()));
+ auto decl
+ = CanonicalPath::new_seg (trait.get_node_id (), trait.get_identifier ());
+ auto path = prefix.append (decl);
+ auto cpath = canonical_prefix.append (decl);
+
resolver->get_type_scope ().insert (
path, trait.get_node_id (), trait.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
@@ -308,7 +387,10 @@ public:
});
for (auto &item : trait.get_trait_items ())
- ResolveTopLevelTraitItems::go (item.get (), path);
+ ResolveTopLevelTraitItems::go (item.get (), path, cpath);
+
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ trait.get_node_id (), cpath);
}
void visit (AST::ExternBlock &extern_block) override
@@ -320,11 +402,14 @@ public:
}
private:
- ResolveTopLevel (const CanonicalPath &prefix)
- : ResolverBase (UNKNOWN_NODEID), prefix (prefix)
+ ResolveTopLevel (const CanonicalPath &prefix,
+ const CanonicalPath &canonical_prefix)
+ : ResolverBase (UNKNOWN_NODEID), prefix (prefix),
+ canonical_prefix (canonical_prefix)
{}
const CanonicalPath &prefix;
+ const CanonicalPath &canonical_prefix;
};
} // namespace Resolver
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h
index 97c4dd8..f7bdc9e 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.h
+++ b/gcc/rust/resolve/rust-ast-resolve-type.h
@@ -250,9 +250,11 @@ class ResolveType : public ResolverBase
public:
static NodeId go (AST::Type *type, NodeId parent,
- bool canonicalize_type_with_generics = false)
+ bool canonicalize_type_with_generics = false,
+ CanonicalPath *canonical_path = nullptr)
{
- ResolveType resolver (parent, canonicalize_type_with_generics);
+ ResolveType resolver (parent, canonicalize_type_with_generics,
+ canonical_path);
type->accept_vis (resolver);
if (!resolver.ok)
rust_error_at (type->get_locus (), "unresolved type");
@@ -285,35 +287,52 @@ public:
void visit (AST::TypePath &path) override
{
- auto canonical_path
+ auto rel_canonical_path
= ResolveTypeToCanonicalPath::resolve (path,
canonicalize_type_with_generics,
true);
- if (canonical_path.is_empty ())
+ if (rel_canonical_path.is_empty ())
{
rust_error_at (path.get_locus (),
"Failed to resolve canonical path for TypePath");
return;
}
- ok = !canonical_path.is_empty ();
+ ok = !rel_canonical_path.is_empty ();
// lets try and resolve in one go else leave it up to the type resolver to
// figure outer
- if (resolver->get_type_scope ().lookup (canonical_path, &resolved_node))
+ if (resolver->get_type_scope ().lookup (rel_canonical_path, &resolved_node))
{
resolver->insert_resolved_type (path.get_node_id (), resolved_node);
resolver->insert_new_definition (path.get_node_id (),
Definition{path.get_node_id (),
parent});
+
+ if (canonical_path != nullptr)
+ {
+ const CanonicalPath *cpath = nullptr;
+ bool ok
+ = mappings->lookup_canonical_path (mappings->get_current_crate (),
+ resolved_node, &cpath);
+ if (!ok)
+ {
+ *canonical_path = rel_canonical_path;
+ }
+ else
+ {
+ *canonical_path = *cpath;
+ }
+ }
+
return;
}
// lets resolve as many segments as we can and leave it up to the type
// resolver otherwise
size_t nprocessed = 0;
- canonical_path.iterate ([&] (const CanonicalPath &seg) -> bool {
+ rel_canonical_path.iterate ([&] (const CanonicalPath &seg) -> bool {
resolved_node = UNKNOWN_NODEID;
if (!resolver->get_type_scope ().lookup (seg, &resolved_node))
@@ -336,12 +355,22 @@ public:
// its ok if this fails since the type resolver sometimes will need to
// investigate the bounds of a type for the associated type for example see:
// https://github.com/Rust-GCC/gccrs/issues/746
- if (nprocessed == canonical_path.size ())
+ if (nprocessed == rel_canonical_path.size ())
{
resolver->insert_resolved_type (path.get_node_id (), resolved_node);
resolver->insert_new_definition (path.get_node_id (),
Definition{path.get_node_id (),
parent});
+
+ if (canonical_path != nullptr)
+ {
+ const CanonicalPath *cpath = nullptr;
+ bool ok
+ = mappings->lookup_canonical_path (mappings->get_current_crate (),
+ resolved_node, &cpath);
+ rust_assert (ok);
+ *canonical_path = *cpath;
+ }
}
}
@@ -356,6 +385,13 @@ public:
void visit (AST::ReferenceType &type) override
{
type.get_type_referenced ()->accept_vis (*this);
+
+ if (canonical_path != nullptr && canonical_path->size () > 0)
+ {
+ std::string seg = canonical_path->get ();
+ *canonical_path
+ = CanonicalPath::new_seg (type.get_node_id (), "&" + seg);
+ }
}
void visit (AST::InferredType &type) override { ok = true; }
@@ -363,6 +399,13 @@ public:
void visit (AST::RawPointerType &type) override
{
type.get_type_pointed_to ()->accept_vis (*this);
+
+ if (canonical_path != nullptr && canonical_path->size () > 0)
+ {
+ std::string seg = canonical_path->get ();
+ *canonical_path
+ = CanonicalPath::new_seg (type.get_node_id (), "*" + seg);
+ }
}
void visit (AST::TraitObjectTypeOneBound &type) override;
@@ -370,14 +413,16 @@ public:
void visit (AST::TraitObjectType &type) override;
private:
- ResolveType (NodeId parent, bool canonicalize_type_with_generics)
+ ResolveType (NodeId parent, bool canonicalize_type_with_generics,
+ CanonicalPath *canonical_path)
: ResolverBase (parent),
canonicalize_type_with_generics (canonicalize_type_with_generics),
- ok (false)
+ ok (false), canonical_path (canonical_path)
{}
bool canonicalize_type_with_generics;
bool ok;
+ CanonicalPath *canonical_path;
};
class ResolveTypeBound : public ResolverBase
@@ -453,16 +498,18 @@ public:
}
}
- // for now lets focus on handling the basics: like struct<T> { a:T, ....}
+ auto seg = CanonicalPath::new_seg (param.get_node_id (),
+ param.get_type_representation ());
resolver->get_type_scope ().insert (
- CanonicalPath::new_seg (param.get_node_id (),
- param.get_type_representation ()),
- param.get_node_id (), param.get_locus (), false,
+ seg, param.get_node_id (), param.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
rust_error_at (param.get_locus (),
"generic param redefined multiple times");
rust_error_at (locus, "was defined here");
});
+
+ mappings->insert_canonical_path (mappings->get_current_crate (),
+ param.get_node_id (), seg);
}
private:
@@ -483,7 +530,10 @@ public:
clause->accept_vis (r);
}
- void visit (AST::LifetimeWhereClauseItem &) override {}
+ void visit (AST::LifetimeWhereClauseItem &) override
+ {
+ // nothing to do
+ }
void visit (AST::TypeBoundWhereClauseItem &item) override
{
@@ -499,7 +549,7 @@ public:
private:
ResolveWhereClause (NodeId parent) : ResolverBase (parent) {}
-}; // namespace Resolver
+};
} // namespace Resolver
} // namespace Rust
diff --git a/gcc/rust/resolve/rust-ast-resolve.cc b/gcc/rust/resolve/rust-ast-resolve.cc
index a34e631..96524d2 100644
--- a/gcc/rust/resolve/rust-ast-resolve.cc
+++ b/gcc/rust/resolve/rust-ast-resolve.cc
@@ -313,6 +313,13 @@ NameResolution::Resolve (AST::Crate &crate)
void
NameResolution::go (AST::Crate &crate)
{
+ // lookup current crate name
+ CrateNum cnum = mappings->get_current_crate ();
+ std::string crate_name;
+ bool ok = mappings->get_crate_name (cnum, crate_name);
+ rust_assert (ok);
+
+ // setup the ribs
NodeId scope_node_id = crate.get_node_id ();
resolver->get_name_scope ().push (scope_node_id);
resolver->get_type_scope ().push (scope_node_id);
@@ -321,16 +328,25 @@ NameResolution::go (AST::Crate &crate)
resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
- // first gather the top-level namespace names then we drill down
+ // get the root segment
+ CanonicalPath crate_prefix
+ = CanonicalPath::new_seg (scope_node_id, crate_name);
+ crate_prefix.set_crate_num (cnum);
+
+ // first gather the top-level namespace names then we drill down so this
+ // allows for resolving forward declarations since an impl block might have
+ // a Self type Foo which is defined after the impl block for example.
for (auto it = crate.items.begin (); it != crate.items.end (); it++)
- ResolveTopLevel::go (it->get ());
+ ResolveTopLevel::go (it->get (), CanonicalPath::create_empty (),
+ crate_prefix);
+ // FIXME remove this
if (saw_errors ())
return;
// next we can drill down into the items and their scopes
for (auto it = crate.items.begin (); it != crate.items.end (); it++)
- ResolveItem::go (it->get ());
+ ResolveItem::go (it->get (), CanonicalPath::create_empty (), crate_prefix);
}
// rust-ast-resolve-expr.h
@@ -349,17 +365,19 @@ ResolveExpr::visit (AST::BlockExpr &expr)
for (auto &s : expr.get_statements ())
{
if (s->is_item ())
- ResolveStmt::go (s.get (), s->get_node_id ());
+ ResolveStmt::go (s.get (), s->get_node_id (), prefix, canonical_prefix,
+ CanonicalPath::create_empty ());
}
for (auto &s : expr.get_statements ())
{
if (!s->is_item ())
- ResolveStmt::go (s.get (), s->get_node_id ());
+ ResolveStmt::go (s.get (), s->get_node_id (), prefix, canonical_prefix,
+ CanonicalPath::create_empty ());
}
if (expr.has_tail_expr ())
- ResolveExpr::go (expr.get_tail_expr ().get (), expr.get_node_id ());
+ resolve_expr (expr.get_tail_expr ().get (), expr.get_node_id ());
resolver->get_name_scope ().pop ();
resolver->get_type_scope ().pop ();
@@ -371,13 +389,15 @@ ResolveExpr::visit (AST::BlockExpr &expr)
void
ResolveStructExprField::visit (AST::StructExprFieldIdentifierValue &field)
{
- ResolveExpr::go (field.get_value ().get (), field.get_node_id ());
+ ResolveExpr::go (field.get_value ().get (), field.get_node_id (), prefix,
+ canonical_prefix);
}
void
ResolveStructExprField::visit (AST::StructExprFieldIndexValue &field)
{
- ResolveExpr::go (field.get_value ().get (), field.get_node_id ());
+ ResolveExpr::go (field.get_value ().get (), field.get_node_id (), prefix,
+ canonical_prefix);
}
void
@@ -386,7 +406,7 @@ ResolveStructExprField::visit (AST::StructExprFieldIdentifier &field)
AST::IdentifierExpr expr (field.get_field_name (), {}, field.get_locus ());
expr.set_node_id (field.get_node_id ());
- ResolveExpr::go (&expr, field.get_node_id ());
+ ResolveExpr::go (&expr, field.get_node_id (), prefix, canonical_prefix);
}
// rust-ast-resolve-type.h
@@ -746,7 +766,12 @@ void
ResolveType::visit (AST::ArrayType &type)
{
type.get_elem_type ()->accept_vis (*this);
- ResolveExpr::go (type.get_size_expr ().get (), type.get_node_id ());
+ // FIXME
+ // the capacity expr can contain block-expr with functions but these should be
+ // folded via constexpr code
+ ResolveExpr::go (type.get_size_expr ().get (), type.get_node_id (),
+ CanonicalPath::create_empty (),
+ CanonicalPath::create_empty ());
}
void
@@ -771,15 +796,19 @@ ResolveType::visit (AST::TraitObjectType &type)
// rust-ast-resolve-item.h
void
-ResolveItem::resolve_impl_item (AST::TraitImplItem *item)
+ResolveItem::resolve_impl_item (AST::TraitImplItem *item,
+ const CanonicalPath &prefix,
+ const CanonicalPath &canonical_prefix)
{
- ResolveImplItems::go (item);
+ ResolveImplItems::go (item, prefix, canonical_prefix);
}
void
-ResolveItem::resolve_impl_item (AST::InherentImplItem *item)
+ResolveItem::resolve_impl_item (AST::InherentImplItem *item,
+ const CanonicalPath &prefix,
+ const CanonicalPath &canonical_prefix)
{
- ResolveImplItems::go (item);
+ ResolveImplItems::go (item, prefix, canonical_prefix);
}
void
diff --git a/gcc/rust/resolve/rust-name-resolver.h b/gcc/rust/resolve/rust-name-resolver.h
index ac00d58..199b0f9 100644
--- a/gcc/rust/resolve/rust-name-resolver.h
+++ b/gcc/rust/resolve/rust-name-resolver.h
@@ -39,6 +39,7 @@ public:
~Rib () {}
+ // this takes the relative paths of items within a compilation unit for lookup
void insert_name (
const CanonicalPath &path, NodeId id, Location locus, bool shadow,
std::function<void (const CanonicalPath &, NodeId, Location)> dup_cb)
@@ -60,7 +61,6 @@ public:
reverse_path_mappings.insert (std::pair<NodeId, CanonicalPath> (id, path));
decls_within_rib.insert (std::pair<NodeId, Location> (id, locus));
references[id] = {};
- mappings->insert_canonical_path (mappings->get_current_crate (), id, path);
}
bool lookup_name (const CanonicalPath &ident, NodeId *id)
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index c930f55..83f35ff 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -69,7 +69,7 @@ const char *kHIRDumpFile = "gccrs.hir.dump";
const char *kHIRTypeResolutionDumpFile = "gccrs.type-resolution.dump";
const char *kTargetOptionsDumpFile = "gccrs.target-options.dump";
-const std::string kDefaultCrateName = "TestCrate";
+const std::string kDefaultCrateName = "example";
// Implicitly enable a target_feature (and recursively enable dependencies).
void
diff --git a/gcc/rust/util/rust-canonical-path.h b/gcc/rust/util/rust-canonical-path.h
index 8473df6..9b34075 100644
--- a/gcc/rust/util/rust-canonical-path.h
+++ b/gcc/rust/util/rust-canonical-path.h
@@ -57,7 +57,8 @@ public:
static CanonicalPath new_seg (NodeId id, const std::string &path)
{
rust_assert (!path.empty ());
- return CanonicalPath ({std::pair<NodeId, std::string> (id, path)});
+ return CanonicalPath ({std::pair<NodeId, std::string> (id, path)},
+ UNKNOWN_CREATENUM);
}
std::string get () const
@@ -77,7 +78,10 @@ public:
return CanonicalPath::new_seg (id, "Self");
}
- static CanonicalPath create_empty () { return CanonicalPath ({}); }
+ static CanonicalPath create_empty ()
+ {
+ return CanonicalPath ({}, UNKNOWN_CREATENUM);
+ }
bool is_empty () const { return segs.size () == 0; }
@@ -85,13 +89,13 @@ public:
{
rust_assert (!other.is_empty ());
if (is_empty ())
- return CanonicalPath (other.segs);
+ return CanonicalPath (other.segs, crate_num);
std::vector<std::pair<NodeId, std::string>> copy (segs);
for (auto &s : other.segs)
copy.push_back (s);
- return CanonicalPath (copy);
+ return CanonicalPath (copy, crate_num);
}
// if we have the path A::B::C this will give a callback for each segment
@@ -110,7 +114,7 @@ public:
for (auto &seg : segs)
{
buf.push_back (seg);
- if (!cb (CanonicalPath (buf)))
+ if (!cb (CanonicalPath (buf, crate_num)))
return;
}
}
@@ -131,7 +135,7 @@ public:
{
std::vector<std::pair<NodeId, std::string>> buf;
buf.push_back ({seg.first, seg.second});
- if (!cb (CanonicalPath (buf)))
+ if (!cb (CanonicalPath (buf, crate_num)))
return;
}
}
@@ -144,21 +148,37 @@ public:
return segs.back ().first;
}
+ const std::pair<NodeId, std::string> &get_seg_at (size_t index) const
+ {
+ rust_assert (index < size ());
+ return segs.at (index);
+ }
+
bool is_equal (const CanonicalPath &b) const
{
return get ().compare (b.get ()) == 0;
}
+ void set_crate_num (CrateNum n) { crate_num = n; }
+
+ CrateNum get_crate_num () const
+ {
+ rust_assert (crate_num != UNKNOWN_CREATENUM);
+ return crate_num;
+ }
+
bool operator== (const CanonicalPath &b) const { return is_equal (b); }
bool operator< (const CanonicalPath &b) const { return get () < b.get (); }
private:
- explicit CanonicalPath (std::vector<std::pair<NodeId, std::string>> path)
- : segs (path)
+ explicit CanonicalPath (std::vector<std::pair<NodeId, std::string>> path,
+ CrateNum crate_num)
+ : segs (path), crate_num (crate_num)
{}
std::vector<std::pair<NodeId, std::string>> segs;
+ CrateNum crate_num;
};
} // namespace Resolver
diff --git a/gcc/testsuite/rust/compile/canonical_paths1.rs b/gcc/testsuite/rust/compile/canonical_paths1.rs
new file mode 100644
index 0000000..af547ef
--- /dev/null
+++ b/gcc/testsuite/rust/compile/canonical_paths1.rs
@@ -0,0 +1,25 @@
+// { dg-additional-options "-w -fdump-tree-gimple" }
+struct Foo(i32);
+
+trait TR {
+ fn test(&self) -> i32;
+}
+
+mod A {
+ impl ::Foo {
+ pub fn test(self) {}
+ // { dg-final { scan-tree-dump-times {example::A::<impl example::Foo>::test} 2 gimple } }
+ }
+
+ impl ::TR for ::Foo {
+ fn test(&self) -> i32 {
+ // { dg-final { scan-tree-dump-times {example::A::<impl example::Foo as example::TR>::test} 1 gimple } }
+ self.0
+ }
+ }
+}
+
+pub fn test() {
+ let a = Foo(123);
+ a.test();
+}
diff --git a/gcc/testsuite/rust/compile/torture/mod3.rs b/gcc/testsuite/rust/compile/torture/mod3.rs
index e241839..2ace8c0 100644
--- a/gcc/testsuite/rust/compile/torture/mod3.rs
+++ b/gcc/testsuite/rust/compile/torture/mod3.rs
@@ -1,25 +1,22 @@
+// { dg-additional-options "-w" }
mod A {
- pub mod B { // { dg-warning "unused name" }
- pub mod C { // { dg-warning "unused name" }
+ pub mod B {
+ pub mod C {
pub struct Foo {
pub f: i32,
}
impl Foo {
- pub fn new() -> Self { // { dg-warning "unused name" }
- Foo {
- f: 23i32,
- }
+ pub fn new() -> Self {
+ Foo { f: 23i32 }
}
}
}
}
}
-fn main() ->i32 {
+fn main() -> i32 {
let a = A::B::C::Foo::new();
- let b = A::B::C::Foo {
- f: -23i32,
- };
+ let b = A::B::C::Foo { f: -23i32 };
a.f - b.f
}
diff --git a/gcc/testsuite/rust/compile/traits9.rs b/gcc/testsuite/rust/compile/traits9.rs
index e1aef539..7ef577a 100644
--- a/gcc/testsuite/rust/compile/traits9.rs
+++ b/gcc/testsuite/rust/compile/traits9.rs
@@ -8,6 +8,6 @@ fn main() {
a = Foo(123);
let b: &dyn Bar = &a;
- // { dg-error "bounds not satisfied for Foo .Bar. is not satisfied" "" { target *-*-* } .-1 }
+ // { dg-error "bounds not satisfied for Foo .example::Bar. is not satisfied" "" { target *-*-* } .-1 }
// { dg-error "expected" "" { target *-*-* } .-2 }
}