Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add late name resolution pass #2620

Closed
wants to merge 26 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
8c6d4da
immutable nrctx: new
CohenArthur Aug 24, 2023
ab87d01
sesh: [wip][from here tests don't work] Add late name resolution 2.0
CohenArthur Aug 4, 2023
12e8a39
tests: [wip] [fmeup] delete failing tests for now
CohenArthur Nov 14, 2023
22115df
session-manager: [fix me] Start dumping name resolution pass
CohenArthur Aug 23, 2023
af8c0bd
session manager: Init Immutable name resolver
CohenArthur Aug 24, 2023
7da69cb
nrctx: add resolved lookup
CohenArthur Aug 24, 2023
5a19a7c
typecheck: [tests fail from here] [needs f'ed up commits] Fetch Immut…
CohenArthur Aug 24, 2023
62f1371
typecheck: Start using nr2.0 properly
CohenArthur Aug 25, 2023
29b7c5d
backend: Use new name resolver where necessary [needs f'ed up commits]
CohenArthur Aug 25, 2023
f49671c
nr2.0: Start using newtype pattern for Usage and Declaration
CohenArthur Sep 14, 2023
c04726a
late: Setup builtin types properly, change Rib API
CohenArthur Aug 28, 2023
67f1b28
typecheck path: wip
CohenArthur Aug 29, 2023
df77f79
toplevel: Add note about resolving glob imports
CohenArthur Aug 29, 2023
230a037
default: Visit external functions properly
CohenArthur Aug 29, 2023
1719fb3
add more name res test casaes
CohenArthur Aug 23, 2023
ee4ac05
Fix duplicate detection
P-E-P Sep 14, 2023
723cc17
Change to new resolution 2.0
P-E-P Sep 15, 2023
5ba2a90
Change to name resolution 2.0
P-E-P Sep 15, 2023
4783b1f
Emit error on identical use declarations
P-E-P Sep 15, 2023
fbfca21
Change unresolved import error text
P-E-P Sep 15, 2023
cae4a70
Change name resolution version in test
P-E-P Sep 15, 2023
d60af27
Change name resolution algorithm in one test
P-E-P Sep 15, 2023
825b224
Change name resolution algorithm in test
P-E-P Sep 15, 2023
966932c
Prevent error emission on resolver reentry
P-E-P Sep 18, 2023
15afef4
late: Add bool builtin type
CohenArthur Nov 8, 2023
022d75c
tests: Re-add macro nr2.0 test cases
CohenArthur Nov 14, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions gcc/rust/Make-lang.in
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ GRS_OBJS = \
rust/rust-toplevel-name-resolver-2.0.o \
rust/rust-early-name-resolver-2.0.o \
rust/rust-late-name-resolver-2.0.o \
rust/rust-immutable-name-resolution-context.o \
rust/rust-early-name-resolver.o \
rust/rust-name-resolver.o \
rust/rust-ast-resolve.o \
Expand Down
1 change: 1 addition & 0 deletions gcc/rust/backend/rust-compile-base.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "rust-type-util.h"
#include "rust-compile-implitem.h"
#include "rust-attribute-values.h"
#include "rust-immutable-name-resolution-context.h"

#include "fold-const.h"
#include "stringpool.h"
Expand Down
1 change: 1 addition & 0 deletions gcc/rust/backend/rust-compile-context.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "rust-hir-full.h"
#include "rust-mangle.h"
#include "rust-tree.h"
#include "rust-immutable-name-resolution-context.h"

namespace Rust {
namespace Compile {
Expand Down
22 changes: 17 additions & 5 deletions gcc/rust/backend/rust-compile-expr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2313,11 +2313,23 @@ CompileExpr::generate_closure_function (HIR::ClosureExpr &expr,
if (is_block_expr)
{
auto body_mappings = function_body->get_mappings ();
Resolver::Rib *rib = nullptr;
bool ok
= ctx->get_resolver ()->find_name_rib (body_mappings.get_nodeid (),
&rib);
rust_assert (ok);
if (flag_name_resolution_2_0)
{
auto nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();

auto candidate = nr_ctx.values.to_rib (body_mappings.get_nodeid ());

rust_assert (candidate.has_value ());
}
else
{
Resolver::Rib *rib = nullptr;
bool ok
= ctx->get_resolver ()->find_name_rib (body_mappings.get_nodeid (),
&rib);
rust_assert (ok);
}
}

tree enclosing_scope = NULL_TREE;
Expand Down
33 changes: 27 additions & 6 deletions gcc/rust/backend/rust-compile-item.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "rust-compile-item.h"
#include "rust-compile-implitem.h"
#include "rust-compile-extern.h"
#include "rust-immutable-name-resolution-context.h"

namespace Rust {
namespace Compile {
Expand Down Expand Up @@ -149,12 +150,32 @@ CompileItem::visit (HIR::Function &function)
}
}

const Resolver::CanonicalPath *canonical_path = nullptr;
bool ok = ctx->get_mappings ()->lookup_canonical_path (
function.get_mappings ().get_nodeid (), &canonical_path);
rust_assert (ok);
Resolver::CanonicalPath canonical_path
= Resolver::CanonicalPath::create_empty ();

if (flag_name_resolution_2_0)
{
// FIXME: What we need to do here is build the CanonicalPath from the name
// resolver 2.0. this isn't super difficult, we just need to get to it
auto nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();

auto path = nr_ctx.values.to_canonical_path (
function.get_mappings ().get_nodeid ());

canonical_path = path.value ();
}
else
{
const Resolver::CanonicalPath *path = nullptr;
bool ok = ctx->get_mappings ()->lookup_canonical_path (
function.get_mappings ().get_nodeid (), &path);
rust_assert (ok);

canonical_path = *path;
}

const std::string asm_name = ctx->mangle_item (fntype, *canonical_path);
const std::string asm_name = ctx->mangle_item (fntype, canonical_path);

// items can be forward compiled which means we may not need to invoke this
// code. We might also have already compiled this generic function as well.
Expand All @@ -181,7 +202,7 @@ CompileItem::visit (HIR::Function &function)
function.get_function_params (),
function.get_qualifiers (), function.get_visibility (),
function.get_outer_attrs (), function.get_locus (),
function.get_definition ().get (), canonical_path,
function.get_definition ().get (), &canonical_path,
fntype);
reference = address_expression (fndecl, ref_locus);

Expand Down
16 changes: 14 additions & 2 deletions gcc/rust/resolve/rust-default-resolver.cc
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ DefaultResolver::visit (AST::Function &function)

if (function.has_body ())
function.get_definition ().value ()->accept_vis (*this);

// TODO: Don't we need to visit the return type here as well?
};

ctx.scoped (Rib::Kind::Function, function.get_node_id (), def_fn);
Expand Down Expand Up @@ -427,8 +429,18 @@ DefaultResolver::visit (AST::ExternalStaticItem &)
{}

void
DefaultResolver::visit (AST::ExternalFunctionItem &)
{}
DefaultResolver::visit (AST::ExternalFunctionItem &function)
{
auto def_fn = [this, &function] () {
for (auto &param : function.get_function_params ())
{
// TODO: So extern function params are not patterns?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rustc will parse any pattern, but it's an error if the pattern is anything other than an identifier or _ after expansion.

param.get_type ()->accept_vis (*this);
}
};

ctx.scoped (Rib::Kind::Function, function.get_node_id (), def_fn);
}

void
DefaultResolver::visit (AST::MacroMatchRepetition &)
Expand Down
22 changes: 13 additions & 9 deletions gcc/rust/resolve/rust-forever-stack.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,9 @@ ForeverStack<N>::pop ()
}

static tl::expected<NodeId, DuplicateNameError>
insert_inner (Rib &rib, std::string name, NodeId node, bool can_shadow)
insert_inner (Rib &rib, std::string name, Rib::Definition definition)
{
return rib.insert (name, node, can_shadow);
return rib.insert (name, definition);
}

template <Namespace N>
Expand All @@ -115,7 +115,8 @@ ForeverStack<N>::insert (Identifier name, NodeId node)
// pass, we might end up in a situation where it is okay to re-add new names.
// Do we just ignore that here? Do we keep track of if the Rib is new or not?
// should our cursor have info on the current node like "is it newly pushed"?
return insert_inner (innermost_rib, name.as_string (), node, false);
return insert_inner (innermost_rib, name.as_string (),
Rib::Definition::NonShadowable (node));
}

template <Namespace N>
Expand All @@ -126,7 +127,8 @@ ForeverStack<N>::insert_at_root (Identifier name, NodeId node)

// inserting in the root of the crate is never a shadowing operation, even for
// macros
return insert_inner (root_rib, name.as_string (), node, false);
return insert_inner (root_rib, name.as_string (),
Rib::Definition::NonShadowable (node));
}

// Specialization for Macros and Labels - where we are allowed to shadow
Expand All @@ -135,14 +137,16 @@ template <>
inline tl::expected<NodeId, DuplicateNameError>
ForeverStack<Namespace::Macros>::insert (Identifier name, NodeId node)
{
return insert_inner (peek (), name.as_string (), node, true);
return insert_inner (peek (), name.as_string (),
Rib::Definition::Shadowable (node));
}

template <>
inline tl::expected<NodeId, DuplicateNameError>
ForeverStack<Namespace::Labels>::insert (Identifier name, NodeId node)
{
return insert_inner (peek (), name.as_string (), node, true);
return insert_inner (peek (), name.as_string (),
Rib::Definition::Shadowable (node));
}

template <Namespace N>
Expand Down Expand Up @@ -455,10 +459,10 @@ template <Namespace N>
tl::optional<std::pair<typename ForeverStack<N>::Node &, std::string>>
ForeverStack<N>::dfs (ForeverStack<N>::Node &starting_point, NodeId to_find)
{
auto &values = starting_point.rib.get_values ();
auto values = starting_point.rib.get_values ();

for (auto &kv : values)
if (kv.second == to_find)
if (kv.second.id == to_find)
return {{starting_point, kv.first}};

for (auto &child : starting_point.children)
Expand Down Expand Up @@ -568,7 +572,7 @@ ForeverStack<N>::stream_rib (std::stringstream &stream, const Rib &rib,
stream << next << "rib: {\n";

for (const auto &kv : rib.get_values ())
stream << next_next << kv.first << ": " << kv.second << "\n";
stream << next_next << kv.first << ": " << kv.second.id << "\n";

stream << next << "},\n";
}
Expand Down
56 changes: 56 additions & 0 deletions gcc/rust/resolve/rust-immutable-name-resolution-context.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright (C) 2020-2023 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-immutable-name-resolution-context.h"

namespace Rust {
namespace Resolver2_0 {

static ImmutableNameResolutionContext *instance = nullptr;

const ImmutableNameResolutionContext &
ImmutableNameResolutionContext::init (const NameResolutionContext &ctx)
{
rust_assert (!instance);

instance = new ImmutableNameResolutionContext (ctx);

return *instance;
}

const ImmutableNameResolutionContext &
ImmutableNameResolutionContext::get ()
{
rust_assert (instance);

return *instance;
}

const NameResolutionContext &
ImmutableNameResolutionContext::resolver () const
{
return ctx;
}

ImmutableNameResolutionContext::ImmutableNameResolutionContext (
const NameResolutionContext &ctx)
: ctx (ctx)
{}

} // namespace Resolver2_0
} // namespace Rust
55 changes: 55 additions & 0 deletions gcc/rust/resolve/rust-immutable-name-resolution-context.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright (C) 2020-2023 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_IMMUTABLE_NRCTX_H
#define RUST_IMMUTABLE_NRCTX_H

#include "rust-name-resolution-context.h"

namespace Rust {
namespace Resolver2_0 {

/**
* Once the name resolution pass is complete, the typechecker can access it
*
* FIXME: More documentation
*/
class ImmutableNameResolutionContext
{
public:
/** FIXME: Documentation */
static const ImmutableNameResolutionContext &
init (const NameResolutionContext &ctx);

/** FIXME: Documentation */
static const ImmutableNameResolutionContext &get ();

const NameResolutionContext &resolver () const;

private:
ImmutableNameResolutionContext (const NameResolutionContext &ctx);
ImmutableNameResolutionContext (const ImmutableNameResolutionContext &other)
= default;

const NameResolutionContext &ctx;
};

} // namespace Resolver2_0
} // namespace Rust

#endif //! RUST_IMMUTABLE_NRCTX_H
Loading
Loading