Skip to content

Commit 45f80a2

Browse files
Merge #1514
1514: Fix SEGV in transcribe_type when compiling libcore 1.29 r=CohenArthur a=CohenArthur Needs #1513, Skip reviewing the first commit Co-authored-by: Arthur Cohen <[email protected]>
2 parents 017be6a + fcf6fea commit 45f80a2

File tree

4 files changed

+77
-10
lines changed

4 files changed

+77
-10
lines changed

gcc/rust/ast/rust-ast-dump.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,22 @@ class Dump : public ASTVisitor
5252
void go (AST::Crate &crate);
5353
void go (AST::Item &item);
5454

55+
/**
56+
* Use the AST Dump as a debugging tool
57+
*/
58+
template <typename T> static void debug (T &instance)
59+
{
60+
auto dump = Dump (std::cerr);
61+
62+
std::cerr << '\n';
63+
instance.accept_vis (dump);
64+
std::cerr << '\n';
65+
}
66+
template <typename T> static void debug (std::unique_ptr<T> &instance)
67+
{
68+
debug (*instance);
69+
}
70+
5571
private:
5672
std::ostream &stream;
5773
Indent indentation;

gcc/rust/ast/rust-ast.h

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "rust-hir-map.h"
2525
#include "rust-token.h"
2626
#include "rust-location.h"
27+
#include "rust-diagnostics.h"
2728

2829
namespace Rust {
2930
// TODO: remove typedefs and make actual types for these
@@ -1818,7 +1819,7 @@ class SingleASTNode
18181819
return true;
18191820
}
18201821

1821-
std::string as_string ()
1822+
std::string as_string () const
18221823
{
18231824
switch (kind)
18241825
{
@@ -1869,9 +1870,44 @@ class ASTFragment
18691870

18701871
bool is_single_fragment () const { return nodes.size () == 1; }
18711872

1872-
bool is_single_fragment_kind (SingleASTNode::NodeType kind) const
1873+
bool is_single_fragment_of_kind (SingleASTNode::NodeType expected) const
18731874
{
1874-
return is_single_fragment () && nodes[0].get_kind () == kind;
1875+
return is_single_fragment () && nodes[0].get_kind () == expected;
1876+
}
1877+
1878+
void assert_single_fragment (SingleASTNode::NodeType expected) const
1879+
{
1880+
static const std::map<SingleASTNode::NodeType, const char *> str_map = {
1881+
{SingleASTNode::NodeType::IMPL, "impl"},
1882+
{SingleASTNode::NodeType::ITEM, "item"},
1883+
{SingleASTNode::NodeType::TYPE, "type"},
1884+
{SingleASTNode::NodeType::EXPRESSION, "expr"},
1885+
{SingleASTNode::NodeType::STMT, "stmt"},
1886+
{SingleASTNode::NodeType::EXTERN, "extern"},
1887+
{SingleASTNode::NodeType::TRAIT, "trait"},
1888+
{SingleASTNode::NodeType::TRAIT_IMPL, "trait impl"},
1889+
};
1890+
1891+
auto actual = nodes[0].get_kind ();
1892+
auto fail = false;
1893+
1894+
if (!is_single_fragment ())
1895+
{
1896+
rust_error_at (Location (), "fragment is not single");
1897+
fail = true;
1898+
}
1899+
1900+
if (actual != expected)
1901+
{
1902+
rust_error_at (
1903+
Location (),
1904+
"invalid fragment operation: expected %qs node, got %qs node",
1905+
str_map.find (expected)->second,
1906+
str_map.find (nodes[0].get_kind ())->second);
1907+
fail = true;
1908+
}
1909+
1910+
rust_assert (!fail);
18751911
}
18761912

18771913
public:
@@ -1913,15 +1949,25 @@ class ASTFragment
19131949

19141950
bool should_expand () const { return !is_error (); }
19151951

1952+
bool is_expression_fragment () const
1953+
{
1954+
return is_single_fragment_of_kind (SingleASTNode::NodeType::EXPRESSION);
1955+
}
1956+
1957+
bool is_type_fragment () const
1958+
{
1959+
return is_single_fragment_of_kind (SingleASTNode::NodeType::TYPE);
1960+
}
1961+
19161962
std::unique_ptr<Expr> take_expression_fragment ()
19171963
{
1918-
rust_assert (is_single_fragment_kind (SingleASTNode::NodeType::EXPRESSION));
1964+
assert_single_fragment (SingleASTNode::NodeType::EXPRESSION);
19191965
return nodes[0].take_expr ();
19201966
}
19211967

19221968
std::unique_ptr<Type> take_type_fragment ()
19231969
{
1924-
rust_assert (is_single_fragment_kind (SingleASTNode::NodeType::TYPE));
1970+
assert_single_fragment (SingleASTNode::NodeType::TYPE);
19251971
return nodes[0].take_type ();
19261972
}
19271973

gcc/rust/expand/rust-attribute-visitor.cc

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2662,7 +2662,7 @@ AttrVisitor::visit (AST::InherentImpl &impl)
26622662
for (auto &param : impl.get_generic_params ())
26632663
param->accept_vis (*this);
26642664

2665-
expander.push_context (MacroExpander::ContextType::TYPE);
2665+
expander.push_context (MacroExpander::ContextType::ITEM);
26662666

26672667
auto &type = impl.get_type ();
26682668
type->accept_vis (*this);
@@ -2706,7 +2706,7 @@ AttrVisitor::visit (AST::TraitImpl &impl)
27062706
for (auto &param : impl.get_generic_params ())
27072707
param->accept_vis (*this);
27082708

2709-
expander.push_context (MacroExpander::ContextType::TYPE);
2709+
expander.push_context (MacroExpander::ContextType::ITEM);
27102710

27112711
auto &type = impl.get_type ();
27122712
type->accept_vis (*this);
@@ -3427,19 +3427,22 @@ AttrVisitor::visit (AST::BareFunctionType &type)
34273427

34283428
// no where clause, apparently
34293429
}
3430+
34303431
void
34313432
AttrVisitor::maybe_expand_expr (std::unique_ptr<AST::Expr> &expr)
34323433
{
34333434
auto final_fragment = expand_macro_fragment_recursive ();
3434-
if (final_fragment.should_expand ())
3435+
if (final_fragment.should_expand ()
3436+
&& final_fragment.is_expression_fragment ())
34353437
expr = final_fragment.take_expression_fragment ();
34363438
}
34373439

34383440
void
34393441
AttrVisitor::maybe_expand_type (std::unique_ptr<AST::Type> &type)
34403442
{
34413443
auto final_fragment = expand_macro_fragment_recursive ();
3442-
if (final_fragment.should_expand ())
3444+
if (final_fragment.should_expand () && final_fragment.is_type_fragment ())
34433445
type = final_fragment.take_type_fragment ();
34443446
}
3447+
34453448
} // namespace Rust

gcc/rust/expand/rust-macro-expand.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -864,7 +864,9 @@ transcribe_expression (Parser<MacroInvocLexer> &parser)
864864
static AST::ASTFragment
865865
transcribe_type (Parser<MacroInvocLexer> &parser)
866866
{
867-
auto type = parser.parse_type ();
867+
auto type = parser.parse_type (true);
868+
for (auto err : parser.get_errors ())
869+
err.emit_error ();
868870

869871
return AST::ASTFragment ({std::move (type)});
870872
}

0 commit comments

Comments
 (0)