Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
Harishankar14 authored Dec 5, 2024
2 parents cfb6ef8 + 7208108 commit 06742a8
Show file tree
Hide file tree
Showing 9 changed files with 196 additions and 9 deletions.
3 changes: 2 additions & 1 deletion gcc/rust/Make-lang.in
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,9 @@ GRS_OBJS = \
rust/rust-dir-owner.o \
rust/rust-unicode.o \
rust/rust-punycode.o \
rust/rust-lang-item.o \
rust/rust-expand-format-args.o \
rust/rust-lang-item.o \
rust/rust-collect-lang-items.o \
$(END)
# removed object files from here

Expand Down
86 changes: 86 additions & 0 deletions gcc/rust/ast/rust-collect-lang-items.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Copyright (C) 2024 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-collect-lang-items.h"
#include "optional.h"
#include "rust-ast-collector.h"
#include "rust-ast.h"
#include "rust-attribute-values.h"
#include "rust-attributes.h"
#include "rust-hir-map.h"

namespace Rust {
namespace AST {

template <typename T>
tl::optional<LangItem::Kind>
get_lang_item_attr (const T &maybe_lang_item)
{
for (const auto &attr : maybe_lang_item.get_outer_attrs ())
{
const auto &str_path = attr.get_path ().as_string ();
if (!Analysis::Attributes::is_known (str_path))
{
rust_error_at (attr.get_locus (), "unknown attribute");
continue;
}

bool is_lang_item = str_path == Values::Attributes::LANG
&& attr.has_attr_input ()
&& attr.get_attr_input ().get_attr_input_type ()
== AST::AttrInput::AttrInputType::LITERAL;

if (is_lang_item)
{
auto &literal
= static_cast<AST::AttrInputLiteral &> (attr.get_attr_input ());
const auto &lang_item_type_str = literal.get_literal ().as_string ();

return LangItem::Parse (lang_item_type_str);
}
}

return tl::nullopt;
}

template <typename T>
void
CollectLangItems::maybe_add_lang_item (const T &item)
{
if (auto lang_item = get_lang_item_attr (item))
mappings.insert_lang_item_node (lang_item.value (), item.get_node_id ());
}

void
CollectLangItems::visit (AST::Trait &item)
{
maybe_add_lang_item (item);

DefaultASTVisitor::visit (item);
}

void
CollectLangItems::visit (AST::TraitItemType &item)
{
maybe_add_lang_item (item);

DefaultASTVisitor::visit (item);
}

} // namespace AST
} // namespace Rust
58 changes: 58 additions & 0 deletions gcc/rust/ast/rust-collect-lang-items.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright (C) 2024 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_COLLECT_LANG_ITEMS_H
#define RUST_COLLECT_LANG_ITEMS_H

#include "rust-ast-visitor.h"
#include "rust-ast.h"
#include "rust-hir-map.h"
#include "rust-item.h"

namespace Rust {
namespace AST {

// This class collects lang items ahead of lowering, as they are now needed for
// some parts of name resolution
class CollectLangItems : public DefaultASTVisitor
{
public:
CollectLangItems () : mappings (Analysis::Mappings::get ()){};

void go (AST::Crate &crate) { DefaultASTVisitor::visit (crate); }

Analysis::Mappings &mappings;

// We must implement visitors for all constructs that could be lang items.
// Lang items can be traits, but also enums, and even enum variants.
//
// https://github.com/rust-lang/rust/blob/master/compiler/rustc_hir/src/lang_items.rs

using DefaultASTVisitor::visit;

void visit (AST::Trait &item) override;
void visit (AST::TraitItemType &item) override;

private:
template <typename T> void maybe_add_lang_item (const T &item);
};

} // namespace AST
} // namespace Rust

#endif // ! RUST_COLLECT_LANG_ITEMS_H
10 changes: 2 additions & 8 deletions gcc/rust/hir/rust-ast-lower-base.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "rust-diagnostics.h"
#include "rust-item.h"
#include "rust-system.h"
#include "rust-attributes.h"

namespace Rust {
namespace HIR {
Expand Down Expand Up @@ -751,7 +752,7 @@ ASTLoweringBase::handle_outer_attributes (const ItemWrapper &item)
for (const auto &attr : item.get_outer_attrs ())
{
const auto &str_path = attr.get_path ().as_string ();
if (!is_known_attribute (str_path))
if (!Analysis::Attributes::is_known (str_path))
{
rust_error_at (attr.get_locus (), "unknown attribute");
continue;
Expand Down Expand Up @@ -814,13 +815,6 @@ ASTLoweringBase::handle_lang_item_attribute (const ItemWrapper &item,
rust_error_at (attr.get_locus (), "unknown lang item");
}

bool
ASTLoweringBase::is_known_attribute (const std::string &attribute_path) const
{
const auto &lookup = attr_mappings->lookup_builtin (attribute_path);
return !lookup.is_error ();
}

bool
ASTLoweringBase::attribute_handled_in_another_pass (
const std::string &attribute_path) const
Expand Down
3 changes: 3 additions & 0 deletions gcc/rust/rust-session-manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
// <http://www.gnu.org/licenses/>.

#include "rust-session-manager.h"
#include "rust-collect-lang-items.h"
#include "rust-diagnostics.h"
#include "rust-hir-pattern-analysis.h"
#include "rust-immutable-name-resolution-context.h"
Expand Down Expand Up @@ -600,6 +601,8 @@ Session::compile_crate (const char *filename)
if (last_step == CompileOptions::CompileStep::Expansion)
return;

AST::CollectLangItems ().go (parsed_crate);

auto name_resolution_ctx = Resolver2_0::NameResolutionContext ();
// expansion pipeline stage

Expand Down
9 changes: 9 additions & 0 deletions gcc/rust/util/rust-attributes.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@
namespace Rust {
namespace Analysis {

bool
Attributes::is_known (const std::string &attribute_path)
{
const auto &lookup
= BuiltinAttributeMappings::get ()->lookup_builtin (attribute_path);

return !lookup.is_error ();
}

using Attrs = Values::Attributes;

// https://doc.rust-lang.org/stable/nightly-rustc/src/rustc_feature/builtin_attrs.rs.html#248
Expand Down
6 changes: 6 additions & 0 deletions gcc/rust/util/rust-attributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@
namespace Rust {
namespace Analysis {

class Attributes
{
public:
static bool is_known (const std::string &attribute_path);
};

enum CompilerPass
{
UNKNOWN,
Expand Down
22 changes: 22 additions & 0 deletions gcc/rust/util/rust-hir-map.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1241,6 +1241,9 @@ Mappings::lookup_builtin_marker ()
return builtinMarker;
}

// FIXME: Before merging: Should we remove the `locus` parameter here? since
// lang items are looked up mostly for code generation, it doesn't make sense to
// error out on the locus of the node trying to access an inexistant lang item
DefId
Mappings::get_lang_item (LangItem::Kind item_type, location_t locus)
{
Expand Down Expand Up @@ -1277,5 +1280,24 @@ Mappings::lookup_lang_item (LangItem::Kind item_type)
return it->second;
}

void
Mappings::insert_lang_item_node (LangItem::Kind item_type, NodeId node_id)
{
auto it = lang_item_nodes.find (item_type);
rust_assert (it == lang_item_nodes.end ());

lang_item_nodes.insert ({item_type, node_id});
}

tl::optional<NodeId &>
Mappings::lookup_lang_item_node (LangItem::Kind item_type)
{
auto it = lang_item_nodes.find (item_type);
if (it == lang_item_nodes.end ())
return tl::nullopt;

return it->second;
}

} // namespace Analysis
} // namespace Rust
8 changes: 8 additions & 0 deletions gcc/rust/util/rust-hir-map.h
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,9 @@ class Mappings
void insert_lang_item (LangItem::Kind item_type, DefId id);
tl::optional<DefId &> lookup_lang_item (LangItem::Kind item_type);

void insert_lang_item_node (LangItem::Kind item_type, NodeId node_id);
tl::optional<NodeId &> lookup_lang_item_node (LangItem::Kind item_type);

// This will fatal_error when this lang item does not exist
DefId get_lang_item (LangItem::Kind item_type, location_t locus);

Expand Down Expand Up @@ -375,7 +378,12 @@ class Mappings
std::map<HirId, HIR::GenericParam *> hirGenericParamMappings;
std::map<HirId, HIR::Trait *> hirTraitItemsToTraitMappings;
std::map<HirId, HIR::Pattern *> hirPatternMappings;

// We need to have two maps here, as lang-items need to be used for both AST
// passes and HIR passes. Thus those two maps are created at different times.
std::map<LangItem::Kind, DefId> lang_item_mappings;
std::map<LangItem::Kind, NodeId> lang_item_nodes;

std::map<NodeId, Resolver::CanonicalPath> paths;
std::map<NodeId, location_t> locations;
std::map<NodeId, HirId> nodeIdToHirMappings;
Expand Down

0 comments on commit 06742a8

Please sign in to comment.