aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/resolve/rust-ast-resolve-expr.h
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-04-10 15:31:29 +0100
committerPhilip Herron <philip.herron@embecosm.com>2021-04-12 22:39:45 +0100
commit85f587410612c8d2ec65dd23063a849d13005957 (patch)
treebecd4a2fe59042dc35cbaae862403105b5ead1df /gcc/rust/resolve/rust-ast-resolve-expr.h
parent5fe4984806be69154e2a48be58965eb67a4be300 (diff)
downloadgcc-85f587410612c8d2ec65dd23063a849d13005957.zip
gcc-85f587410612c8d2ec65dd23063a849d13005957.tar.gz
gcc-85f587410612c8d2ec65dd23063a849d13005957.tar.bz2
Add Canonical paths to name resolution
In order to support name resolution and checks for duplicate definitions of names we need canonical paths for all DefId items such as inherent impl items and normal items. Consider: struct Foo<T>(T); impl Foo<f32> { fn name()... } impl Foo<i32> { fn name()... } Each of the impl blocks have a name function but these are seperate due to the concrete impl of the Parameter type passed in. The caveat here is that to call this Function name the programmer must be explicit in which implentation they wish to call such as: let a = Foo::<f32>::name(); This lets the Path probe lookup the apropriate impl block. The problem here is that rust also allows for the compiler to infer the impl you wish such as: let a = Foo::name(); This should fail since there are multiple candidates possible for this Path. Unless there might have only been one name function in which case it would have worked. This does not support looking for any inherent impl items overlapping such as: rustc_typeck/src/coherence/inherent_impls_overlap.rs - see #353 Fixes #355 #335 #325
Diffstat (limited to 'gcc/rust/resolve/rust-ast-resolve-expr.h')
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-expr.h25
1 files changed, 14 insertions, 11 deletions
diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.h b/gcc/rust/resolve/rust-ast-resolve-expr.h
index 48cc18e..fbf05f2 100644
--- a/gcc/rust/resolve/rust-ast-resolve-expr.h
+++ b/gcc/rust/resolve/rust-ast-resolve-expr.h
@@ -109,15 +109,16 @@ public:
void visit (AST::IdentifierExpr &expr) override
{
- if (resolver->get_name_scope ().lookup (expr.as_string (), &resolved_node))
+ if (resolver->get_name_scope ().lookup (CanonicalPath (expr.as_string ()),
+ &resolved_node))
{
resolver->insert_resolved_name (expr.get_node_id (), resolved_node);
resolver->insert_new_definition (expr.get_node_id (),
Definition{expr.get_node_id (),
parent});
}
- else if (resolver->get_type_scope ().lookup (expr.as_string (),
- &resolved_node))
+ else if (resolver->get_type_scope ().lookup (
+ CanonicalPath (expr.as_string ()), &resolved_node))
{
resolver->insert_resolved_type (expr.get_node_id (), resolved_node);
resolver->insert_new_definition (expr.get_node_id (),
@@ -255,8 +256,9 @@ public:
auto label_name = label.get_lifetime ().get_lifetime_name ();
auto label_lifetime_node_id = label.get_lifetime ().get_node_id ();
resolver->get_label_scope ().insert (
- label_name, label_lifetime_node_id, label.get_locus (), false,
- [&] (std::string, NodeId, Location locus) -> void {
+ CanonicalPath (label_name), label_lifetime_node_id,
+ label.get_locus (), false,
+ [&] (const CanonicalPath &, NodeId, Location locus) -> void {
rust_error_at (label.get_locus (),
"label redefined multiple times");
rust_error_at (locus, "was defined here");
@@ -281,8 +283,8 @@ public:
}
NodeId resolved_node = UNKNOWN_NODEID;
- if (!resolver->get_label_scope ().lookup (label.get_lifetime_name (),
- &resolved_node))
+ if (!resolver->get_label_scope ().lookup (
+ CanonicalPath (label.get_lifetime_name ()), &resolved_node))
{
rust_error_at (expr.get_label ().get_locus (),
"failed to resolve label");
@@ -311,8 +313,9 @@ public:
auto label_name = label.get_lifetime ().get_lifetime_name ();
auto label_lifetime_node_id = label.get_lifetime ().get_node_id ();
resolver->get_label_scope ().insert (
- label_name, label_lifetime_node_id, label.get_locus (), false,
- [&] (std::string, NodeId, Location locus) -> void {
+ CanonicalPath (label_name), label_lifetime_node_id,
+ label.get_locus (), false,
+ [&] (const CanonicalPath &, NodeId, Location locus) -> void {
rust_error_at (label.get_locus (),
"label redefined multiple times");
rust_error_at (locus, "was defined here");
@@ -338,8 +341,8 @@ public:
}
NodeId resolved_node = UNKNOWN_NODEID;
- if (!resolver->get_label_scope ().lookup (label.get_lifetime_name (),
- &resolved_node))
+ if (!resolver->get_label_scope ().lookup (
+ CanonicalPath (label.get_lifetime_name ()), &resolved_node))
{
rust_error_at (expr.get_label ().get_locus (),
"failed to resolve label");