aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorArthur Cohen <arthur.cohen@embecosm.com>2022-04-27 16:34:37 +0200
committerArthur Cohen <arthur.cohen@embecosm.com>2022-04-27 16:34:37 +0200
commit10b01c305ff73a9da40fb81b7f90312d1f79f037 (patch)
tree07689ae1cbd6c05fb9923ebb2f1de5e06a40674c /gcc
parentd69dd650367fa7fcfac38001b6406c1bff2601e1 (diff)
downloadgcc-10b01c305ff73a9da40fb81b7f90312d1f79f037.zip
gcc-10b01c305ff73a9da40fb81b7f90312d1f79f037.tar.gz
gcc-10b01c305ff73a9da40fb81b7f90312d1f79f037.tar.bz2
ast: ResolvePath: Move into its own source file
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/Make-lang.in1
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-expr.cc1
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-expr.h29
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-path.cc276
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-path.h49
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-pattern.cc1
-rw-r--r--gcc/rust/resolve/rust-ast-resolve.cc237
7 files changed, 328 insertions, 266 deletions
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 5fa93a0..f59deb8 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -91,6 +91,7 @@ GRS_OBJS = \
rust/rust-ast-resolve-pattern.o \
rust/rust-ast-resolve-expr.o \
rust/rust-ast-resolve-type.o \
+ rust/rust-ast-resolve-path.o \
rust/rust-hir-type-check.o \
rust/rust-privacy-check.o \
rust/rust-privacy-ctx.o \
diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.cc b/gcc/rust/resolve/rust-ast-resolve-expr.cc
index e551802..71af8c2 100644
--- a/gcc/rust/resolve/rust-ast-resolve-expr.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-expr.cc
@@ -22,6 +22,7 @@
#include "rust-ast-verify-assignee.h"
#include "rust-ast-resolve-type.h"
#include "rust-ast-resolve-pattern.h"
+#include "rust-ast-resolve-path.h"
namespace Rust {
namespace Resolver {
diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.h b/gcc/rust/resolve/rust-ast-resolve-expr.h
index a049ba1..34a318d 100644
--- a/gcc/rust/resolve/rust-ast-resolve-expr.h
+++ b/gcc/rust/resolve/rust-ast-resolve-expr.h
@@ -25,35 +25,6 @@
namespace Rust {
namespace Resolver {
-class ResolvePath : public ResolverBase
-{
- using Rust::Resolver::ResolverBase::visit;
-
-public:
- static void go (AST::PathInExpression *expr, NodeId parent)
- {
- ResolvePath resolver (parent);
- resolver.resolve_path (expr);
- }
-
- static void go (AST::QualifiedPathInExpression *expr, NodeId parent)
- {
- ResolvePath resolver (parent);
- resolver.resolve_path (expr);
- }
-
-private:
- ResolvePath (NodeId parent) : ResolverBase (parent) {}
-
- void resolve_path (AST::PathInExpression *expr);
-
- void resolve_path (AST::QualifiedPathInExpression *expr);
-
- void resolve_segments (CanonicalPath prefix, size_t offs,
- std::vector<AST::PathExprSegment> &segs,
- NodeId expr_node_id, Location expr_locus);
-};
-
class ResolveExpr : public ResolverBase
{
using Rust::Resolver::ResolverBase::visit;
diff --git a/gcc/rust/resolve/rust-ast-resolve-path.cc b/gcc/rust/resolve/rust-ast-resolve-path.cc
new file mode 100644
index 0000000..7aec4f8
--- /dev/null
+++ b/gcc/rust/resolve/rust-ast-resolve-path.cc
@@ -0,0 +1,276 @@
+// Copyright (C) 2020-2022 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/>.
+
+#include "rust-ast-resolve-path.h"
+#include "rust-ast-resolve-type.h"
+#include "rust-path.h"
+
+namespace Rust {
+namespace Resolver {
+
+void
+ResolvePath::go (AST::PathInExpression *expr, NodeId parent)
+{
+ ResolvePath resolver (parent);
+ resolver.resolve_path (expr);
+}
+
+void
+ResolvePath::go (AST::QualifiedPathInExpression *expr, NodeId parent)
+{
+ ResolvePath resolver (parent);
+ resolver.resolve_path (expr);
+}
+
+void
+ResolvePath::resolve_path (AST::PathInExpression *expr)
+{
+ // resolve root segment first then apply segments in turn
+ std::vector<AST::PathExprSegment> &segs = expr->get_segments ();
+ AST::PathExprSegment &root_segment = segs.at (0);
+ AST::PathIdentSegment &root_ident_seg = root_segment.get_ident_segment ();
+
+ bool segment_is_type = false;
+ CanonicalPath root_seg_path
+ = CanonicalPath::new_seg (root_segment.get_node_id (),
+ root_ident_seg.as_string ());
+
+ // name scope first
+ if (resolver->get_name_scope ().lookup (root_seg_path, &resolved_node))
+ {
+ segment_is_type = false;
+ resolver->insert_resolved_name (root_segment.get_node_id (),
+ resolved_node);
+ resolver->insert_new_definition (root_segment.get_node_id (),
+ Definition{expr->get_node_id (),
+ parent});
+ }
+ // check the type scope
+ else if (resolver->get_type_scope ().lookup (root_seg_path, &resolved_node))
+ {
+ segment_is_type = true;
+ resolver->insert_resolved_type (root_segment.get_node_id (),
+ resolved_node);
+ resolver->insert_new_definition (root_segment.get_node_id (),
+ Definition{expr->get_node_id (),
+ parent});
+ }
+ else
+ {
+ rust_error_at (expr->get_locus (),
+ "Cannot find path %<%s%> in this scope",
+ root_segment.as_string ().c_str ());
+ return;
+ }
+
+ if (root_segment.has_generic_args ())
+ {
+ bool ok = ResolveTypeToCanonicalPath::type_resolve_generic_args (
+ root_segment.get_generic_args ());
+ if (!ok)
+ {
+ rust_error_at (root_segment.get_locus (),
+ "failed to resolve generic arguments");
+ return;
+ }
+ }
+
+ bool is_single_segment = segs.size () == 1;
+ if (is_single_segment)
+ {
+ if (segment_is_type)
+ resolver->insert_resolved_type (expr->get_node_id (), resolved_node);
+ else
+ resolver->insert_resolved_name (expr->get_node_id (), resolved_node);
+
+ resolver->insert_new_definition (expr->get_node_id (),
+ Definition{expr->get_node_id (),
+ parent});
+ return;
+ }
+
+ resolve_segments (root_seg_path, 1, expr->get_segments (),
+ expr->get_node_id (), expr->get_locus ());
+}
+
+void
+ResolvePath::resolve_path (AST::QualifiedPathInExpression *expr)
+{
+ AST::QualifiedPathType &root_segment = expr->get_qualified_path_type ();
+
+ bool canonicalize_type_with_generics = false;
+ ResolveType::go (&root_segment.get_as_type_path (),
+ root_segment.get_node_id (),
+ canonicalize_type_with_generics);
+
+ ResolveType::go (root_segment.get_type ().get (), root_segment.get_node_id (),
+ canonicalize_type_with_generics);
+
+ bool type_resolve_generic_args = true;
+ CanonicalPath impl_type_seg
+ = ResolveTypeToCanonicalPath::resolve (*root_segment.get_type ().get (),
+ canonicalize_type_with_generics,
+ type_resolve_generic_args);
+
+ CanonicalPath trait_type_seg
+ = ResolveTypeToCanonicalPath::resolve (root_segment.get_as_type_path (),
+ canonicalize_type_with_generics,
+ type_resolve_generic_args);
+ CanonicalPath root_seg_path
+ = TraitImplProjection::resolve (root_segment.get_node_id (), trait_type_seg,
+ impl_type_seg);
+ bool segment_is_type = false;
+
+ // name scope first
+ if (resolver->get_name_scope ().lookup (root_seg_path, &resolved_node))
+ {
+ segment_is_type = false;
+ resolver->insert_resolved_name (root_segment.get_node_id (),
+ resolved_node);
+ resolver->insert_new_definition (root_segment.get_node_id (),
+ Definition{expr->get_node_id (),
+ parent});
+ }
+ // check the type scope
+ else if (resolver->get_type_scope ().lookup (root_seg_path, &resolved_node))
+ {
+ segment_is_type = true;
+ resolver->insert_resolved_type (root_segment.get_node_id (),
+ resolved_node);
+ resolver->insert_new_definition (root_segment.get_node_id (),
+ Definition{expr->get_node_id (),
+ parent});
+ }
+ else
+ {
+ rust_error_at (expr->get_locus (),
+ "Cannot find path %<%s%> in this scope",
+ root_segment.as_string ().c_str ());
+ return;
+ }
+
+ bool is_single_segment = expr->get_segments ().empty ();
+ if (is_single_segment)
+ {
+ if (segment_is_type)
+ resolver->insert_resolved_type (expr->get_node_id (), resolved_node);
+ else
+ resolver->insert_resolved_name (expr->get_node_id (), resolved_node);
+
+ resolver->insert_new_definition (expr->get_node_id (),
+ Definition{expr->get_node_id (),
+ parent});
+ return;
+ }
+
+ resolve_segments (root_seg_path, 0, expr->get_segments (),
+ expr->get_node_id (), expr->get_locus ());
+}
+
+void
+ResolvePath::resolve_segments (CanonicalPath prefix, size_t offs,
+ std::vector<AST::PathExprSegment> &segs,
+ NodeId expr_node_id, Location expr_locus)
+{
+ // we can attempt to resolve this path fully
+ CanonicalPath path = prefix;
+ bool segment_is_type = false;
+ for (size_t i = offs; i < segs.size (); i++)
+ {
+ AST::PathExprSegment &seg = segs.at (i);
+ auto s = ResolvePathSegmentToCanonicalPath::resolve (seg);
+ path = path.append (s);
+
+ // reset state
+ segment_is_type = false;
+ resolved_node = UNKNOWN_NODEID;
+
+ if (resolver->get_name_scope ().lookup (path, &resolved_node))
+ {
+ resolver->insert_resolved_name (seg.get_node_id (), resolved_node);
+ resolver->insert_new_definition (seg.get_node_id (),
+ Definition{expr_node_id, parent});
+ }
+ // check the type scope
+ else if (resolver->get_type_scope ().lookup (path, &resolved_node))
+ {
+ segment_is_type = true;
+ resolver->insert_resolved_type (seg.get_node_id (), resolved_node);
+ resolver->insert_new_definition (seg.get_node_id (),
+ Definition{expr_node_id, parent});
+ }
+ else
+ {
+ // attempt to fully resolve the path which is allowed to fail given
+ // the following scenario
+ //
+ // https://github.com/Rust-GCC/gccrs/issues/355 Paths are
+ // resolved fully here, there are limitations though imagine:
+ //
+ // struct Foo<A> (A);
+ //
+ // impl Foo<isize> {
+ // fn test() -> ...
+ //
+ // impl Foo<f32> {
+ // fn test() -> ...
+ //
+ // fn main() {
+ // let a:i32 = Foo::test();
+ //
+ // there are multiple paths that test can resolve to Foo::<?>::test
+ // here so we cannot resolve this case
+ //
+ // canonical names:
+ //
+ // struct Foo<A> -> Foo
+ // impl Foo<isize>::fn test -> Foo::isize::test
+ // impl Foo<f32>::fn test -> Foo::f32::test
+ //
+ // Since there is the case we have the following paths for test:
+ //
+ // Foo::isize::test
+ // Foo::f32::test
+ // vs
+ // Foo::test
+ //
+ // but the lookup was simply Foo::test we must rely on type resolution
+ // to figure this type out in a similar fashion to method resolution
+ // with a probe phase
+
+ // nothing more we can do we need the type resolver to try and resolve
+ // this
+ return;
+ }
+ }
+
+ // its fully resolved lets mark it as such
+ if (resolved_node != UNKNOWN_NODEID)
+ {
+ if (segment_is_type)
+ resolver->insert_resolved_type (expr_node_id, resolved_node);
+ else
+ resolver->insert_resolved_name (expr_node_id, resolved_node);
+
+ resolver->insert_new_definition (expr_node_id,
+ Definition{expr_node_id, parent});
+ }
+}
+
+} // namespace Resolver
+} // namespace Rust
diff --git a/gcc/rust/resolve/rust-ast-resolve-path.h b/gcc/rust/resolve/rust-ast-resolve-path.h
new file mode 100644
index 0000000..7a4413b
--- /dev/null
+++ b/gcc/rust/resolve/rust-ast-resolve-path.h
@@ -0,0 +1,49 @@
+// Copyright (C) 2020-2022 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_PATH_H
+#define RUST_AST_RESOLVE_PATH_H
+
+#include "rust-ast-resolve-base.h"
+
+namespace Rust {
+namespace Resolver {
+
+class ResolvePath : public ResolverBase
+{
+ using Rust::Resolver::ResolverBase::visit;
+
+public:
+ static void go (AST::PathInExpression *expr, NodeId parent);
+ static void go (AST::QualifiedPathInExpression *expr, NodeId parent);
+
+private:
+ ResolvePath (NodeId parent) : ResolverBase (parent) {}
+
+ void resolve_path (AST::PathInExpression *expr);
+ void resolve_path (AST::QualifiedPathInExpression *expr);
+
+ void resolve_segments (CanonicalPath prefix, size_t offs,
+ std::vector<AST::PathExprSegment> &segs,
+ NodeId expr_node_id, Location expr_locus);
+};
+
+} // namespace Resolver
+} // namespace Rust
+
+#endif // !RUST_AST_RESOLVE_PATH_H
diff --git a/gcc/rust/resolve/rust-ast-resolve-pattern.cc b/gcc/rust/resolve/rust-ast-resolve-pattern.cc
index 24cd171..bac5521 100644
--- a/gcc/rust/resolve/rust-ast-resolve-pattern.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-pattern.cc
@@ -17,6 +17,7 @@
// <http://www.gnu.org/licenses/>.
#include "rust-ast-resolve-pattern.h"
+#include "rust-ast-resolve-path.h"
#include "rust-ast-resolve-expr.h"
namespace Rust {
diff --git a/gcc/rust/resolve/rust-ast-resolve.cc b/gcc/rust/resolve/rust-ast-resolve.cc
index 723c460..6da5609 100644
--- a/gcc/rust/resolve/rust-ast-resolve.cc
+++ b/gcc/rust/resolve/rust-ast-resolve.cc
@@ -122,243 +122,6 @@ ResolveStructExprField::visit (AST::StructExprFieldIdentifier &field)
ResolveExpr::go (&expr, field.get_node_id (), prefix, canonical_prefix);
}
-// rust-ast-resolve-expr.h
-
-void
-ResolvePath::resolve_path (AST::PathInExpression *expr)
-{
- // resolve root segment first then apply segments in turn
- std::vector<AST::PathExprSegment> &segs = expr->get_segments ();
- AST::PathExprSegment &root_segment = segs.at (0);
- AST::PathIdentSegment &root_ident_seg = root_segment.get_ident_segment ();
-
- bool segment_is_type = false;
- CanonicalPath root_seg_path
- = CanonicalPath::new_seg (root_segment.get_node_id (),
- root_ident_seg.as_string ());
-
- // name scope first
- if (resolver->get_name_scope ().lookup (root_seg_path, &resolved_node))
- {
- segment_is_type = false;
- resolver->insert_resolved_name (root_segment.get_node_id (),
- resolved_node);
- resolver->insert_new_definition (root_segment.get_node_id (),
- Definition{expr->get_node_id (),
- parent});
- }
- // check the type scope
- else if (resolver->get_type_scope ().lookup (root_seg_path, &resolved_node))
- {
- segment_is_type = true;
- resolver->insert_resolved_type (root_segment.get_node_id (),
- resolved_node);
- resolver->insert_new_definition (root_segment.get_node_id (),
- Definition{expr->get_node_id (),
- parent});
- }
- else
- {
- rust_error_at (expr->get_locus (),
- "Cannot find path %<%s%> in this scope",
- root_segment.as_string ().c_str ());
- return;
- }
-
- if (root_segment.has_generic_args ())
- {
- bool ok = ResolveTypeToCanonicalPath::type_resolve_generic_args (
- root_segment.get_generic_args ());
- if (!ok)
- {
- rust_error_at (root_segment.get_locus (),
- "failed to resolve generic arguments");
- return;
- }
- }
-
- bool is_single_segment = segs.size () == 1;
- if (is_single_segment)
- {
- if (segment_is_type)
- resolver->insert_resolved_type (expr->get_node_id (), resolved_node);
- else
- resolver->insert_resolved_name (expr->get_node_id (), resolved_node);
-
- resolver->insert_new_definition (expr->get_node_id (),
- Definition{expr->get_node_id (),
- parent});
- return;
- }
-
- resolve_segments (root_seg_path, 1, expr->get_segments (),
- expr->get_node_id (), expr->get_locus ());
-}
-
-void
-ResolvePath::resolve_path (AST::QualifiedPathInExpression *expr)
-{
- AST::QualifiedPathType &root_segment = expr->get_qualified_path_type ();
-
- bool canonicalize_type_with_generics = false;
- ResolveType::go (&root_segment.get_as_type_path (),
- root_segment.get_node_id (),
- canonicalize_type_with_generics);
-
- ResolveType::go (root_segment.get_type ().get (), root_segment.get_node_id (),
- canonicalize_type_with_generics);
-
- bool type_resolve_generic_args = true;
- CanonicalPath impl_type_seg
- = ResolveTypeToCanonicalPath::resolve (*root_segment.get_type ().get (),
- canonicalize_type_with_generics,
- type_resolve_generic_args);
-
- CanonicalPath trait_type_seg
- = ResolveTypeToCanonicalPath::resolve (root_segment.get_as_type_path (),
- canonicalize_type_with_generics,
- type_resolve_generic_args);
- CanonicalPath root_seg_path
- = TraitImplProjection::resolve (root_segment.get_node_id (), trait_type_seg,
- impl_type_seg);
- bool segment_is_type = false;
-
- // name scope first
- if (resolver->get_name_scope ().lookup (root_seg_path, &resolved_node))
- {
- segment_is_type = false;
- resolver->insert_resolved_name (root_segment.get_node_id (),
- resolved_node);
- resolver->insert_new_definition (root_segment.get_node_id (),
- Definition{expr->get_node_id (),
- parent});
- }
- // check the type scope
- else if (resolver->get_type_scope ().lookup (root_seg_path, &resolved_node))
- {
- segment_is_type = true;
- resolver->insert_resolved_type (root_segment.get_node_id (),
- resolved_node);
- resolver->insert_new_definition (root_segment.get_node_id (),
- Definition{expr->get_node_id (),
- parent});
- }
- else
- {
- rust_error_at (expr->get_locus (),
- "Cannot find path %<%s%> in this scope",
- root_segment.as_string ().c_str ());
- return;
- }
-
- bool is_single_segment = expr->get_segments ().empty ();
- if (is_single_segment)
- {
- if (segment_is_type)
- resolver->insert_resolved_type (expr->get_node_id (), resolved_node);
- else
- resolver->insert_resolved_name (expr->get_node_id (), resolved_node);
-
- resolver->insert_new_definition (expr->get_node_id (),
- Definition{expr->get_node_id (),
- parent});
- return;
- }
-
- resolve_segments (root_seg_path, 0, expr->get_segments (),
- expr->get_node_id (), expr->get_locus ());
-}
-
-void
-ResolvePath::resolve_segments (CanonicalPath prefix, size_t offs,
- std::vector<AST::PathExprSegment> &segs,
- NodeId expr_node_id, Location expr_locus)
-{
- // we can attempt to resolve this path fully
- CanonicalPath path = prefix;
- bool segment_is_type = false;
- for (size_t i = offs; i < segs.size (); i++)
- {
- AST::PathExprSegment &seg = segs.at (i);
- auto s = ResolvePathSegmentToCanonicalPath::resolve (seg);
- path = path.append (s);
-
- // reset state
- segment_is_type = false;
- resolved_node = UNKNOWN_NODEID;
-
- if (resolver->get_name_scope ().lookup (path, &resolved_node))
- {
- resolver->insert_resolved_name (seg.get_node_id (), resolved_node);
- resolver->insert_new_definition (seg.get_node_id (),
- Definition{expr_node_id, parent});
- }
- // check the type scope
- else if (resolver->get_type_scope ().lookup (path, &resolved_node))
- {
- segment_is_type = true;
- resolver->insert_resolved_type (seg.get_node_id (), resolved_node);
- resolver->insert_new_definition (seg.get_node_id (),
- Definition{expr_node_id, parent});
- }
- else
- {
- // attempt to fully resolve the path which is allowed to fail given
- // the following scenario
- //
- // https://github.com/Rust-GCC/gccrs/issues/355 Paths are
- // resolved fully here, there are limitations though imagine:
- //
- // struct Foo<A> (A);
- //
- // impl Foo<isize> {
- // fn test() -> ...
- //
- // impl Foo<f32> {
- // fn test() -> ...
- //
- // fn main() {
- // let a:i32 = Foo::test();
- //
- // there are multiple paths that test can resolve to Foo::<?>::test
- // here so we cannot resolve this case
- //
- // canonical names:
- //
- // struct Foo<A> -> Foo
- // impl Foo<isize>::fn test -> Foo::isize::test
- // impl Foo<f32>::fn test -> Foo::f32::test
- //
- // Since there is the case we have the following paths for test:
- //
- // Foo::isize::test
- // Foo::f32::test
- // vs
- // Foo::test
- //
- // but the lookup was simply Foo::test we must rely on type resolution
- // to figure this type out in a similar fashion to method resolution
- // with a probe phase
-
- // nothing more we can do we need the type resolver to try and resolve
- // this
- return;
- }
- }
-
- // its fully resolved lets mark it as such
- if (resolved_node != UNKNOWN_NODEID)
- {
- if (segment_is_type)
- resolver->insert_resolved_type (expr_node_id, resolved_node);
- else
- resolver->insert_resolved_name (expr_node_id, resolved_node);
-
- resolver->insert_new_definition (expr_node_id,
- Definition{expr_node_id, parent});
- }
-}
-
// rust-ast-resolve-item.h
void