Skip to content

Commit bdfdaef

Browse files
powerboat9P-E-P
authored andcommitted
nr2.0: Handle global paths
gcc/rust/ChangeLog: * resolve/rust-forever-stack.h (ForeverStack::ForeverStack): Initialize extern_prelude. (ForeverStack::resolve_path): Add parameter has_opening_scope_resolution. (ForeverStack::extern_prelude): Add field. * resolve/rust-forever-stack.hxx: Include rust-edition.h. (ForeverStacl::resolve_path): Handle global paths (paths with an opening scope resolution operator). * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Handle global paths. * resolve/rust-name-resolution-context.h (NameResolutionContext::resolve_path): Handle global paths. gcc/testsuite/ChangeLog: * rust/compile/nr2/exclude: Remove entries. Signed-off-by: Owen Avery <[email protected]>
1 parent b8ef598 commit bdfdaef

File tree

5 files changed

+96
-51
lines changed

5 files changed

+96
-51
lines changed

gcc/rust/resolve/rust-forever-stack.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,7 @@ template <Namespace N> class ForeverStack
549549
ForeverStack ()
550550
: root (Node (Rib (Rib::Kind::Normal), UNKNOWN_NODEID)),
551551
lang_prelude (Node (Rib (Rib::Kind::Prelude), UNKNOWN_NODEID, root)),
552+
extern_prelude (Node (Rib (Rib::Kind::Prelude), UNKNOWN_NODEID)),
552553
cursor_reference (root)
553554
{
554555
rust_assert (root.is_root ());
@@ -671,7 +672,7 @@ template <Namespace N> class ForeverStack
671672
*/
672673
template <typename S>
673674
tl::optional<Rib::Definition> resolve_path (
674-
const std::vector<S> &segments,
675+
const std::vector<S> &segments, bool has_opening_scope_resolution,
675676
std::function<void (const S &, NodeId)> insert_segment_resolution);
676677

677678
// FIXME: Documentation
@@ -768,6 +769,10 @@ template <Namespace N> class ForeverStack
768769
* resolution
769770
*/
770771
Node lang_prelude;
772+
/*
773+
* The extern prelude, used for resolving external crates
774+
*/
775+
Node extern_prelude;
771776

772777
std::reference_wrapper<Node> cursor_reference;
773778

gcc/rust/resolve/rust-forever-stack.hxx

Lines changed: 49 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "rust-ast.h"
2121
#include "rust-diagnostics.h"
2222
#include "rust-forever-stack.h"
23+
#include "rust-edition.h"
2324
#include "rust-rib.h"
2425
#include "rust-unwrap-segment.h"
2526
#include "optional.h"
@@ -618,11 +619,24 @@ template <Namespace N>
618619
template <typename S>
619620
tl::optional<Rib::Definition>
620621
ForeverStack<N>::resolve_path (
621-
const std::vector<S> &segments,
622+
const std::vector<S> &segments, bool has_opening_scope_resolution,
622623
std::function<void (const S &, NodeId)> insert_segment_resolution)
623624
{
624625
// TODO: What to do if segments.empty() ?
625626

627+
// handle paths with opening scopes
628+
std::function<void (void)> cleanup_current = [] () {};
629+
if (has_opening_scope_resolution)
630+
{
631+
Node *last_current = &cursor_reference.get ();
632+
if (get_rust_edition () == Edition::E2015)
633+
cursor_reference = root;
634+
else
635+
cursor_reference = extern_prelude;
636+
cleanup_current
637+
= [this, last_current] () { cursor_reference = *last_current; };
638+
}
639+
626640
// if there's only one segment, we just use `get`
627641
if (segments.size () == 1)
628642
{
@@ -633,6 +647,7 @@ ForeverStack<N>::resolve_path (
633647
lang_item.value ());
634648

635649
insert_segment_resolution (seg, seg_id);
650+
cleanup_current ();
636651
// TODO: does NonShadowable matter?
637652
return Rib::Definition::NonShadowable (seg_id);
638653
}
@@ -646,40 +661,44 @@ ForeverStack<N>::resolve_path (
646661

647662
if (res && !res->is_ambiguous ())
648663
insert_segment_resolution (segments.back (), res->get_node_id ());
664+
cleanup_current ();
649665
return res;
650666
}
651667

652668
std::reference_wrapper<Node> starting_point = cursor ();
653669

654-
return find_starting_point (segments, starting_point,
655-
insert_segment_resolution)
656-
.and_then ([this, &segments, &starting_point, &insert_segment_resolution] (
657-
typename std::vector<S>::const_iterator iterator) {
658-
return resolve_segments (starting_point.get (), segments, iterator,
659-
insert_segment_resolution);
660-
})
661-
.and_then ([this, &segments, &insert_segment_resolution] (
662-
Node final_node) -> tl::optional<Rib::Definition> {
663-
// leave resolution within impl blocks to type checker
664-
if (final_node.rib.kind == Rib::Kind::TraitOrImpl)
665-
return tl::nullopt;
666-
667-
auto &seg = unwrap_type_segment (segments.back ());
668-
std::string seg_name = seg.as_string ();
669-
670-
// assuming this can't be a lang item segment
671-
tl::optional<Rib::Definition> res
672-
= resolve_final_segment (final_node, seg_name,
673-
seg.is_lower_self_seg ());
674-
// Ok we didn't find it in the rib, Lets try the prelude...
675-
if (!res)
676-
res = get_lang_prelude (seg_name);
677-
678-
if (res && !res->is_ambiguous ())
679-
insert_segment_resolution (segments.back (), res->get_node_id ());
680-
681-
return res;
682-
});
670+
auto res
671+
= find_starting_point (segments, starting_point, insert_segment_resolution)
672+
.and_then (
673+
[this, &segments, &starting_point, &insert_segment_resolution] (
674+
typename std::vector<S>::const_iterator iterator) {
675+
return resolve_segments (starting_point.get (), segments, iterator,
676+
insert_segment_resolution);
677+
})
678+
.and_then ([this, &segments, &insert_segment_resolution] (
679+
Node final_node) -> tl::optional<Rib::Definition> {
680+
// leave resolution within impl blocks to type checker
681+
if (final_node.rib.kind == Rib::Kind::TraitOrImpl)
682+
return tl::nullopt;
683+
684+
auto &seg = unwrap_type_segment (segments.back ());
685+
std::string seg_name = seg.as_string ();
686+
687+
// assuming this can't be a lang item segment
688+
tl::optional<Rib::Definition> res
689+
= resolve_final_segment (final_node, seg_name,
690+
seg.is_lower_self_seg ());
691+
// Ok we didn't find it in the rib, Lets try the prelude...
692+
if (!res)
693+
res = get_lang_prelude (seg_name);
694+
695+
if (res && !res->is_ambiguous ())
696+
insert_segment_resolution (segments.back (), res->get_node_id ());
697+
698+
return res;
699+
});
700+
cleanup_current ();
701+
return res;
683702
}
684703

685704
template <Namespace N>

gcc/rust/resolve/rust-late-name-resolver-2.0.cc

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -307,8 +307,7 @@ Late::visit (AST::PathInExpression &expr)
307307
return;
308308
}
309309

310-
auto resolved = ctx.resolve_path (expr.get_segments (), Namespace::Values,
311-
Namespace::Types);
310+
auto resolved = ctx.resolve_path (expr, Namespace::Values, Namespace::Types);
312311

313312
if (!resolved)
314313
{
@@ -340,13 +339,9 @@ Late::visit (AST::TypePath &type)
340339

341340
DefaultResolver::visit (type);
342341

343-
// take care of only simple cases
344-
// TODO: remove this?
345-
rust_assert (!type.has_opening_scope_resolution_op ());
346-
347342
// this *should* mostly work
348343
// TODO: make sure typepath-like path resolution (?) is working
349-
auto resolved = ctx.resolve_path (type.get_segments (), Namespace::Types);
344+
auto resolved = ctx.resolve_path (type, Namespace::Types);
350345

351346
if (!resolved.has_value ())
352347
{
@@ -394,8 +389,7 @@ Late::visit (AST::StructExprStruct &s)
394389
visit_inner_attrs (s);
395390
DefaultResolver::visit (s.get_struct_name ());
396391

397-
auto resolved
398-
= ctx.resolve_path (s.get_struct_name ().get_segments (), Namespace::Types);
392+
auto resolved = ctx.resolve_path (s.get_struct_name (), Namespace::Types);
399393

400394
ctx.map_usage (Usage (s.get_struct_name ().get_node_id ()),
401395
Definition (resolved->get_node_id ()));
@@ -409,8 +403,7 @@ Late::visit (AST::StructExprStructBase &s)
409403
DefaultResolver::visit (s.get_struct_name ());
410404
visit (s.get_struct_base ());
411405

412-
auto resolved
413-
= ctx.resolve_path (s.get_struct_name ().get_segments (), Namespace::Types);
406+
auto resolved = ctx.resolve_path (s.get_struct_name (), Namespace::Types);
414407

415408
ctx.map_usage (Usage (s.get_struct_name ().get_node_id ()),
416409
Definition (resolved->get_node_id ()));
@@ -427,8 +420,7 @@ Late::visit (AST::StructExprStructFields &s)
427420
for (auto &field : s.get_fields ())
428421
visit (field);
429422

430-
auto resolved
431-
= ctx.resolve_path (s.get_struct_name ().get_segments (), Namespace::Types);
423+
auto resolved = ctx.resolve_path (s.get_struct_name (), Namespace::Types);
432424

433425
ctx.map_usage (Usage (s.get_struct_name ().get_node_id ()),
434426
Definition (resolved->get_node_id ()));

gcc/rust/resolve/rust-name-resolution-context.h

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ class NameResolutionContext
221221

222222
template <typename S>
223223
tl::optional<Rib::Definition> resolve_path (const std::vector<S> &segments,
224+
bool has_opening_scope_resolution,
224225
Namespace ns)
225226
{
226227
std::function<void (const S &, NodeId)> insert_segment_resolution
@@ -232,33 +233,63 @@ class NameResolutionContext
232233
switch (ns)
233234
{
234235
case Namespace::Values:
235-
return values.resolve_path (segments, insert_segment_resolution);
236+
return values.resolve_path (segments, has_opening_scope_resolution,
237+
insert_segment_resolution);
236238
case Namespace::Types:
237-
return types.resolve_path (segments, insert_segment_resolution);
239+
return types.resolve_path (segments, has_opening_scope_resolution,
240+
insert_segment_resolution);
238241
case Namespace::Macros:
239-
return macros.resolve_path (segments, insert_segment_resolution);
242+
return macros.resolve_path (segments, has_opening_scope_resolution,
243+
insert_segment_resolution);
240244
case Namespace::Labels:
241-
return labels.resolve_path (segments, insert_segment_resolution);
245+
return labels.resolve_path (segments, has_opening_scope_resolution,
246+
insert_segment_resolution);
242247
default:
243248
rust_unreachable ();
244249
}
245250
}
246251

247252
template <typename S, typename... Args>
248253
tl::optional<Rib::Definition> resolve_path (const std::vector<S> &segments,
254+
bool has_opening_scope_resolution,
249255
Args... ns_args)
250256
{
251257
std::initializer_list<Namespace> namespaces = {ns_args...};
252258

253259
for (auto ns : namespaces)
254260
{
255-
if (auto ret = resolve_path (segments, ns))
261+
if (auto ret
262+
= resolve_path (segments, has_opening_scope_resolution, ns))
256263
return ret;
257264
}
258265

259266
return tl::nullopt;
260267
}
261268

269+
template <typename... Args>
270+
tl::optional<Rib::Definition> resolve_path (const AST::SimplePath &path,
271+
Args... ns_args)
272+
{
273+
return resolve_path (path.get_segments (),
274+
path.has_opening_scope_resolution (), ns_args...);
275+
}
276+
277+
template <typename... Args>
278+
tl::optional<Rib::Definition> resolve_path (const AST::PathInExpression &path,
279+
Args... ns_args)
280+
{
281+
return resolve_path (path.get_segments (), path.opening_scope_resolution (),
282+
ns_args...);
283+
}
284+
285+
template <typename... Args>
286+
tl::optional<Rib::Definition> resolve_path (const AST::TypePath &path,
287+
Args... ns_args)
288+
{
289+
return resolve_path (path.get_segments (),
290+
path.has_opening_scope_resolution_op (), ns_args...);
291+
}
292+
262293
private:
263294
/* Map of "usage" nodes which have been resolved to a "definition" node */
264295
std::map<Usage, Definition> resolved_nodes;

gcc/testsuite/rust/compile/nr2/exclude

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ issue-266.rs
2121
derive_clone_enum3.rs
2222
derive-debug1.rs
2323
derive-default1.rs
24-
issue-3402-1.rs
25-
issue-3403.rs
2624
derive-eq-invalid.rs
2725
derive-hash1.rs
2826
torture/alt_patterns1.rs

0 commit comments

Comments
 (0)