Skip to content

Commit e776191

Browse files
committed
nr: Add prelude field to NRCtx, and fill it upon encountering a prelude.
gcc/rust/ChangeLog: * resolve/rust-early-name-resolver-2.0.cc (Early::finalize_glob_import): Save prelude if we find one. * resolve/rust-name-resolution-context.h: Add field. * resolve/rust-toplevel-name-resolver-2.0.cc (has_prelude_import): New function. (TopLevel::visit): Create a prelude glob import if necessary. * resolve/rust-toplevel-name-resolver-2.0.h: Allow glob imports to be prelude imports.
1 parent 77aaf46 commit e776191

File tree

4 files changed

+83
-15
lines changed

4 files changed

+83
-15
lines changed

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,14 @@ Early::finalize_glob_import (NameResolutionContext &ctx,
410410

411411
rust_assert (container);
412412

413+
if (mapping.import_kind.is_prelude)
414+
{
415+
rust_assert (container.value ()->get_item_kind ()
416+
== AST::Item::Kind::Module);
417+
418+
ctx.prelude = container.value ()->get_node_id ();
419+
}
420+
413421
GlobbingVisitor (ctx).go (container.value ());
414422
}
415423

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

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -560,23 +560,63 @@ class NameResolutionContext
560560
if (resolved_nodes.find (Usage (seg_id)) == resolved_nodes.end ())
561561
map_usage (Usage (seg_id), Definition (id));
562562
};
563+
564+
tl::optional<Rib::Definition> resolved = tl::nullopt;
565+
563566
switch (ns)
564567
{
565568
case Namespace::Values:
566-
return values.resolve_path (segments, mode, insert_segment_resolution,
567-
collect_errors);
569+
resolved
570+
= values.resolve_path (segments, mode, insert_segment_resolution,
571+
collect_errors);
572+
break;
568573
case Namespace::Types:
569-
return types.resolve_path (segments, mode, insert_segment_resolution,
570-
collect_errors);
574+
resolved
575+
= types.resolve_path (segments, mode, insert_segment_resolution,
576+
collect_errors);
577+
break;
571578
case Namespace::Macros:
572-
return macros.resolve_path (segments, mode, insert_segment_resolution,
573-
collect_errors);
579+
resolved
580+
= macros.resolve_path (segments, mode, insert_segment_resolution,
581+
collect_errors);
582+
break;
574583
case Namespace::Labels:
575-
return labels.resolve_path (segments, mode, insert_segment_resolution,
576-
collect_errors);
584+
resolved
585+
= labels.resolve_path (segments, mode, insert_segment_resolution,
586+
collect_errors);
587+
break;
577588
default:
578589
rust_unreachable ();
579590
}
591+
592+
// If it fails, switch to std prelude resolution if it exists
593+
if (prelude && !resolved)
594+
{
595+
// TODO: Factor this with the above
596+
switch (ns)
597+
{
598+
case Namespace::Values:
599+
return values.resolve_path (segments, mode,
600+
insert_segment_resolution,
601+
collect_errors, *prelude);
602+
case Namespace::Types:
603+
return types.resolve_path (segments, mode,
604+
insert_segment_resolution,
605+
collect_errors, *prelude);
606+
case Namespace::Macros:
607+
return macros.resolve_path (segments, mode,
608+
insert_segment_resolution,
609+
collect_errors, *prelude);
610+
case Namespace::Labels:
611+
return labels.resolve_path (segments, mode,
612+
insert_segment_resolution,
613+
collect_errors, *prelude);
614+
default:
615+
rust_unreachable ();
616+
}
617+
}
618+
619+
return resolved;
580620
}
581621

582622
template <typename S, typename... Args>
@@ -676,6 +716,9 @@ class NameResolutionContext
676716
std::forward<Args> (args)...);
677717
}
678718

719+
/* If declared with #[prelude_import], the current standard library module */
720+
tl::optional<NodeId> prelude;
721+
679722
private:
680723
/* Map of "usage" nodes which have been resolved to a "definition" node */
681724
std::map<Usage, Definition> resolved_nodes;

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,16 @@ flatten_glob (const AST::UseTreeGlob &glob, std::vector<AST::SimplePath> &paths,
496496
paths.emplace_back (AST::SimplePath ({}, false, glob.get_locus ()));
497497
}
498498

499+
static bool
500+
has_prelude_import (const std::vector<AST::Attribute> &attributes)
501+
{
502+
for (const auto &attr : attributes)
503+
if (attr.get_path ().as_string () == "prelude_import")
504+
return true;
505+
506+
return false;
507+
}
508+
499509
void
500510
TopLevel::visit (AST::UseDeclaration &use)
501511
{
@@ -523,7 +533,8 @@ TopLevel::visit (AST::UseDeclaration &use)
523533

524534
for (auto &&glob : glob_path)
525535
imports.emplace_back (
526-
ImportKind::Glob (std::move (glob), values_rib, types_rib, macros_rib));
536+
ImportKind::Glob (std::move (glob), values_rib, types_rib, macros_rib,
537+
has_prelude_import (use.get_outer_attrs ())));
527538

528539
for (auto &&rebind : rebind_path)
529540
imports.emplace_back (

gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,10 @@ class TopLevel : public DefaultResolver
6767
} kind;
6868

6969
static ImportKind Glob (AST::SimplePath &&to_resolve, Rib &values_rib,
70-
Rib &types_rib, Rib &macros_rib)
70+
Rib &types_rib, Rib &macros_rib, bool is_prelude)
7171
{
7272
return ImportKind (Kind::Glob, std::move (to_resolve), values_rib,
73-
types_rib, macros_rib);
73+
types_rib, macros_rib, is_prelude);
7474
}
7575

7676
static ImportKind Simple (AST::SimplePath &&to_resolve, Rib &values_rib,
@@ -84,8 +84,10 @@ class TopLevel : public DefaultResolver
8484
AST::UseTreeRebind &&rebind, Rib &values_rib,
8585
Rib &types_rib, Rib &macros_rib)
8686
{
87-
return ImportKind (Kind::Rebind, std::move (to_resolve), values_rib,
88-
types_rib, macros_rib, std::move (rebind));
87+
return ImportKind (
88+
Kind::Rebind, std::move (to_resolve), values_rib, types_rib, macros_rib,
89+
false /* is_prelude: rebind imports can never be preludes */,
90+
std::move (rebind));
8991
}
9092

9193
// The path for `Early` to resolve.
@@ -98,13 +100,17 @@ class TopLevel : public DefaultResolver
98100
Rib &types_rib;
99101
Rib &macros_rib;
100102

103+
// Can only be true if we are dealing with a glob import with the
104+
// #[prelude_import] attribute
105+
bool is_prelude = false;
106+
101107
private:
102108
ImportKind (Kind kind, AST::SimplePath &&to_resolve, Rib &values_rib,
103-
Rib &types_rib, Rib &macros_rib,
109+
Rib &types_rib, Rib &macros_rib, bool is_prelude = false,
104110
tl::optional<AST::UseTreeRebind> &&rebind = tl::nullopt)
105111
: kind (kind), to_resolve (std::move (to_resolve)),
106112
rebind (std::move (rebind)), values_rib (values_rib),
107-
types_rib (types_rib), macros_rib (macros_rib)
113+
types_rib (types_rib), macros_rib (macros_rib), is_prelude (is_prelude)
108114
{}
109115
};
110116

0 commit comments

Comments
 (0)