rust_assert (container);
+ if (mapping.import_kind.is_prelude)
+ {
+ rust_assert (container.value ()->get_item_kind ()
+ == AST::Item::Kind::Module);
+
+ ctx.prelude = container.value ()->get_node_id ();
+ }
+
GlobbingVisitor (ctx).go (container.value ());
}
if (resolved_nodes.find (Usage (seg_id)) == resolved_nodes.end ())
map_usage (Usage (seg_id), Definition (id));
};
+
+ tl::optional<Rib::Definition> resolved = tl::nullopt;
+
switch (ns)
{
case Namespace::Values:
- return values.resolve_path (segments, mode, insert_segment_resolution,
- collect_errors);
+ resolved
+ = values.resolve_path (segments, mode, insert_segment_resolution,
+ collect_errors);
+ break;
case Namespace::Types:
- return types.resolve_path (segments, mode, insert_segment_resolution,
- collect_errors);
+ resolved
+ = types.resolve_path (segments, mode, insert_segment_resolution,
+ collect_errors);
+ break;
case Namespace::Macros:
- return macros.resolve_path (segments, mode, insert_segment_resolution,
- collect_errors);
+ resolved
+ = macros.resolve_path (segments, mode, insert_segment_resolution,
+ collect_errors);
+ break;
case Namespace::Labels:
- return labels.resolve_path (segments, mode, insert_segment_resolution,
- collect_errors);
+ resolved
+ = labels.resolve_path (segments, mode, insert_segment_resolution,
+ collect_errors);
+ break;
default:
rust_unreachable ();
}
+
+ // If it fails, switch to std prelude resolution if it exists
+ if (prelude && !resolved)
+ {
+ // TODO: Factor this with the above
+ switch (ns)
+ {
+ case Namespace::Values:
+ return values.resolve_path (segments, mode,
+ insert_segment_resolution,
+ collect_errors, *prelude);
+ case Namespace::Types:
+ return types.resolve_path (segments, mode,
+ insert_segment_resolution,
+ collect_errors, *prelude);
+ case Namespace::Macros:
+ return macros.resolve_path (segments, mode,
+ insert_segment_resolution,
+ collect_errors, *prelude);
+ case Namespace::Labels:
+ return labels.resolve_path (segments, mode,
+ insert_segment_resolution,
+ collect_errors, *prelude);
+ default:
+ rust_unreachable ();
+ }
+ }
+
+ return resolved;
}
template <typename S, typename... Args>
std::forward<Args> (args)...);
}
+ /* If declared with #[prelude_import], the current standard library module */
+ tl::optional<NodeId> prelude;
+
private:
/* Map of "usage" nodes which have been resolved to a "definition" node */
std::map<Usage, Definition> resolved_nodes;
paths.emplace_back (AST::SimplePath ({}, false, glob.get_locus ()));
}
+static bool
+has_prelude_import (const std::vector<AST::Attribute> &attributes)
+{
+ for (const auto &attr : attributes)
+ if (attr.get_path ().as_string () == "prelude_import")
+ return true;
+
+ return false;
+}
+
void
TopLevel::visit (AST::UseDeclaration &use)
{
for (auto &&glob : glob_path)
imports.emplace_back (
- ImportKind::Glob (std::move (glob), values_rib, types_rib, macros_rib));
+ ImportKind::Glob (std::move (glob), values_rib, types_rib, macros_rib,
+ has_prelude_import (use.get_outer_attrs ())));
for (auto &&rebind : rebind_path)
imports.emplace_back (
} kind;
static ImportKind Glob (AST::SimplePath &&to_resolve, Rib &values_rib,
- Rib &types_rib, Rib ¯os_rib)
+ Rib &types_rib, Rib ¯os_rib, bool is_prelude)
{
return ImportKind (Kind::Glob, std::move (to_resolve), values_rib,
- types_rib, macros_rib);
+ types_rib, macros_rib, is_prelude);
}
static ImportKind Simple (AST::SimplePath &&to_resolve, Rib &values_rib,
AST::UseTreeRebind &&rebind, Rib &values_rib,
Rib &types_rib, Rib ¯os_rib)
{
- return ImportKind (Kind::Rebind, std::move (to_resolve), values_rib,
- types_rib, macros_rib, std::move (rebind));
+ return ImportKind (
+ Kind::Rebind, std::move (to_resolve), values_rib, types_rib, macros_rib,
+ false /* is_prelude: rebind imports can never be preludes */,
+ std::move (rebind));
}
// The path for `Early` to resolve.
Rib &types_rib;
Rib ¯os_rib;
+ // Can only be true if we are dealing with a glob import with the
+ // #[prelude_import] attribute
+ bool is_prelude = false;
+
private:
ImportKind (Kind kind, AST::SimplePath &&to_resolve, Rib &values_rib,
- Rib &types_rib, Rib ¯os_rib,
+ Rib &types_rib, Rib ¯os_rib, bool is_prelude = false,
tl::optional<AST::UseTreeRebind> &&rebind = tl::nullopt)
: kind (kind), to_resolve (std::move (to_resolve)),
rebind (std::move (rebind)), values_rib (values_rib),
- types_rib (types_rib), macros_rib (macros_rib)
+ types_rib (types_rib), macros_rib (macros_rib), is_prelude (is_prelude)
{}
};