Commit Graph

192831 Commits

Author SHA1 Message Date
bors[bot] 729bbacbd1
Merge #1066
1066: Fix warning of uninitialized delim_id variable r=CohenArthur a=CohenArthur



Co-authored-by: CohenArthur <arthur.cohen@epita.fr>
2022-03-27 14:15:10 +00:00
CohenArthur 1f8780be70 is_match_compatible: Fix warning of uninitialized delim_id variable
Since all cases in the switch were handled, this was not really a
problem. Still, we should avoid those in case we need to add
delimiters at some point

Co-authored-by: Thomas Schwinge <thomas@schwinge.name>
2022-03-27 14:46:40 +02:00
bors[bot] 5a15694ee2
Merge #1063
1063: Handle :meta fragments properly r=CohenArthur a=CohenArthur

This expands :meta fragments properly and allows us to strip assignment expressions

Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
2022-03-25 11:46:24 +00:00
bors[bot] a7e7234692
Merge #1055
1055: Allow keeping list of last matches to check against r=CohenArthur a=CohenArthur

When trying to figure out if a match can follow another, we must figure
out whether or not that match is in the follow-set of the other. If that
match is zeroable (i.e a repetition using the * or ? kleene operators),
then we must be able to check the match after them: should our current
match not be present, the match after must be part of the follow-set.
This commits allows us to performs such checks properly and to "look
past" zeroable matches. This is not done with any lookahead, simply by
keeping a list of pointers to possible previous matches and checking all
of them for ambiguities.

Addresses #947 
Closes #947 

Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
2022-03-25 10:23:43 +00:00
Arthur Cohen 7fa6e72b1a macros: Parse :meta properly
This allows us to match attribute bodies in macro invocations, which we
can use later down the line to perform conditional compilation
2022-03-25 11:22:18 +01:00
Arthur Cohen 6c99a5a8f1 parser: Move outer attrs properly intoto AssignmentExpr
AssignmentExpressions could not access their outer attributes properly,
since they were being eagerly moved into the `IdentifierExpr` type they
are based on. The base `OperatorExpr` class would thus end up with an
empty vector of outer attributes
2022-03-25 11:22:17 +01:00
Arthur Cohen 2249a4d512 attributes: Allow stripping assignment expressions 2022-03-25 11:22:17 +01:00
Arthur Cohen 7ea35487a2 macros: Allow checking past zeroable matches for follow-set restrictions
When trying to figure out if a match can follow another, we must figure
out whether or not that match is in the follow-set of the other. If that
match is zeroable (i.e a repetition using the * or ? kleene operators),
then we must be able to check the match after them: should our current
match not be present, the match after must be part of the follow-set.
This commits allows us to performs such checks properly and to "look
past" zeroable matches. This is not done with any lookahead, simply by
keeping a list of pointers to possible previous matches and checking all
of them for ambiguities.
2022-03-25 10:28:42 +01:00
bors[bot] 89ad4f21f2
Merge #1062
1062: Properly perform follow set checking on matcher r=CohenArthur a=CohenArthur

Addresses #947 

Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
2022-03-25 07:55:29 +00:00
bors[bot] 0fa882160d
Merge #1043 #1064
1043: implement include_bytes! and include_str! macros r=CohenArthur a=dafaust

Implement the include_bytes! and include_str! builtin macros.

Addresses:  #927 

1064: Handle :tt fragments properly r=CohenArthur a=CohenArthur

:tt fragments stand for token trees, and are composed of either a token,
or a delimited token tree, which is a token tree surrounded by
delimiters (parentheses, curly brackets or square brackets).

This should allow us to handle a lot more macros, including extremely
powerful macro patterns such as TT munchers


Co-authored-by: David Faust <david.faust@oracle.com>
Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
2022-03-24 16:54:54 +00:00
David Faust 261c753e56 macros: implement include_bytes! and include_str! 2022-03-24 08:59:35 -07:00
bors[bot] 3a90596517
Merge #1054
1054: Fix overzealous follow set ambiguity r=CohenArthur a=CohenArthur

When checking if a follow-up is valid, we previously always returned
false when comparing with MacroMatchRepetitions. This is however
invalid, as we should be comparing with the first match of the
repetition to be sure.

Closes #1053 
Addresses #947 

Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
2022-03-24 15:58:07 +00:00
Arthur Cohen 5651331236 macros: Allow parsing :tt fragments
:tt fragments stand for token trees, and are composed of either a token,
or a delimited token tree, which is a token tree surrounded by
delimiters (parentheses, curly brackets or square brackets).

This should allow us to handle a lot more macros, including extremely
powerful macro patterns such as TT munchers
2022-03-24 15:03:20 +01:00
Arthur Cohen 912b04216d macros: Check follow-set restrictions on matcher's first delimiter 2022-03-24 13:56:23 +01:00
Arthur Cohen d859ab0146 macros: Allow repetitions of tokens in follow-set in follow-set
When checking if a follow-up is valid, we previously always returned
false when comparing with MacroMatchRepetitions. This is however
invalid, as we should be comparing with the first match of the
repetition to be sure.
2022-03-24 13:07:22 +01:00
bors[bot] 8283724bc2
Merge #1052
1052: Add hints for valid follow tokens r=CohenArthur a=CohenArthur

This PR adds hints about the allowed tokens after a certain fragment, and fixes tests to uphold the new error message

Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
2022-03-24 10:11:43 +00:00
Arthur Cohen 3e5090608d macros: Add hints for follow-set restrictions
Adds a new call to `rust_inform()` in order to let the user know about
the tokens allowed after the previous match.
Since this changes the error message, tests also need to be adjusted.
2022-03-24 11:11:11 +01:00
Arthur Cohen 14b0472fa4 hir-path-probe: Fix miscompilation on gcc-4.8 2022-03-24 11:05:27 +01:00
Arthur Cohen c1cc931f97 ci: Add job for building gccrs with older gcc
As Thomas Schwinge pointed out, GCC 4.8 is the minimum version to be
used for building current GCC, meaning that we should make an effort to
support it before we consider upstreaming or backporting. The main
differences are probably a less powerful standard template library or
small compilation differences.
2022-03-24 11:05:27 +01:00
bors[bot] ff5f3005d0
Merge #1051
1051: macros: Add remaining restrictions for follow-set restrictions r=CohenArthur a=CohenArthur

Adds the remaining restrictions for follow-set ambiguities in macros.
This means adding the remaining allowed tokens for all fragment
specifiers with follow-up restrictions, as well as handling allowed
fragment specifiers in certain cases. For example, :vis specifiers can
sometimes be followed by fragments, if they have the :ident, :ty or
:path specifier. Likewise for :path and :ty which can be followed by a
:block.

Finally, we also allow *any* fragment after a matcher: Since the matcher
is delimiter by parentheses, brackets or curlies, anything is allowed
afterwards.

Some edge cases or allowed tokens that we cannot handle yet remain, for which FIXMEs exist. I'll open up corresponding issues. 

Addresses #947 

Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
2022-03-24 09:34:19 +00:00
bors[bot] 90f938c2ec
Merge #1056 #1057
1056: Fix '#include <algorithm>' [#159] r=tschwinge a=tschwinge

... recently introduced in #1044 commit 35ca685200
"macros: Add base functions to check for follow-set ambiguities".

GCC doesn't like that:

    In file included from [...]
    ./mm_malloc.h:42:12: error: attempt to use poisoned "malloc"
         return malloc (__size);
                ^

See commit e7b3f654f2, for example.


1057: For use as 'std::unordered_map' key, provide 'std::hash' for 'Rust::AST::MacroFragSpec::Kind' enum class r=tschwinge a=tschwinge

... recently introduced in #1044 commit 35ca685200
"macros: Add base functions to check for follow-set ambiguities".

Otherwise, at least with an oldish GCC 5.2, compilation of
'gcc/rust/parse/rust-parse.cc' fails noisily:

    In file included from [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/hashtable.h:35:0,
                     from [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/unordered_map:47,
                     from [GCC/Rust]/gcc/rust/rust-system.h:46,
                     from [GCC/Rust]/gcc/rust/rust-linemap.h:12,
                     from [GCC/Rust]/gcc/rust/lex/rust-lex.h:22,
                     from [GCC/Rust]/gcc/rust/parse/rust-parse.h:20,
                     from [GCC/Rust]/gcc/rust/parse/rust-parse.cc:17:
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/hashtable_policy.h: In instantiation of 'struct std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> >':
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/type_traits:137:12:   required from 'struct std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > >'
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/type_traits:148:38:   required from 'struct std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h💯66:   required from 'class std::unordered_map<Rust::AST::MacroFragSpec::Kind, std::vector<Rust::TokenId> >'
    [GCC/Rust]/gcc/rust/parse/rust-parse.cc:101:5:   required from here
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/hashtable_policy.h:85:34: error: no match for call to '(const std::hash<Rust::AST::MacroFragSpec::Kind>) (const Rust::AST::MacroFragSpec::Kind&)'
      noexcept(declval<const _Hash&>()(declval<const _Key&>()))>
                                      ^
    In file included from [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/move.h:57:0,
                     from [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/stl_pair.h:59,
                     from [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/stl_algobase.h:64,
                     from [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/char_traits.h:39,
                     from [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/string:40,
                     from [GCC/Rust]/gcc/rust/rust-system.h:34,
                     from [GCC/Rust]/gcc/rust/rust-linemap.h:12,
                     from [GCC/Rust]/gcc/rust/lex/rust-lex.h:22,
                     from [GCC/Rust]/gcc/rust/parse/rust-parse.h:20,
                     from [GCC/Rust]/gcc/rust/parse/rust-parse.cc:17:
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/type_traits: In instantiation of 'struct std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >':
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h💯66:   required from 'class std::unordered_map<Rust::AST::MacroFragSpec::Kind, std::vector<Rust::TokenId> >'
    [GCC/Rust]/gcc/rust/parse/rust-parse.cc:101:5:   required from here
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/type_traits:148:38: error: 'value' is not a member of 'std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > >'
         : public integral_constant<bool, !_Pp::value>
                                          ^
    In file included from [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/unordered_map:48:0,
                     from [GCC/Rust]/gcc/rust/rust-system.h:46,
                     from [GCC/Rust]/gcc/rust/rust-linemap.h:12,
                     from [GCC/Rust]/gcc/rust/lex/rust-lex.h:22,
                     from [GCC/Rust]/gcc/rust/parse/rust-parse.h:20,
                     from [GCC/Rust]/gcc/rust/parse/rust-parse.cc:17:
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h: In instantiation of 'class std::unordered_map<Rust::AST::MacroFragSpec::Kind, std::vector<Rust::TokenId> >':
    [GCC/Rust]/gcc/rust/parse/rust-parse.cc:101:5:   required from here
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h💯66: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           typedef __umap_hashtable<_Key, _Tp, _Hash, _Pred, _Alloc>  _Hashtable;
                                                                      ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:107:45: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           typedef typename _Hashtable::key_type key_type;
                                                 ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:108:47: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           typedef typename _Hashtable::value_type value_type;
                                                   ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:109:48: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           typedef typename _Hashtable::mapped_type mapped_type;
                                                    ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:110:43: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           typedef typename _Hashtable::hasher hasher;
                                               ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:111:46: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           typedef typename _Hashtable::key_equal key_equal;
                                                  ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:112:51: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           typedef typename _Hashtable::allocator_type allocator_type;
                                                       ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:117:45: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           typedef typename _Hashtable::pointer  pointer;
                                                 ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:118:50: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           typedef typename _Hashtable::const_pointer const_pointer;
                                                      ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:119:47: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           typedef typename _Hashtable::reference  reference;
                                                   ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:120:52: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           typedef typename _Hashtable::const_reference const_reference;
                                                        ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:121:46: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           typedef typename _Hashtable::iterator  iterator;
                                                  ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:122:51: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           typedef typename _Hashtable::const_iterator const_iterator;
                                                       ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:123:51: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           typedef typename _Hashtable::local_iterator local_iterator;
                                                       ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:124:57: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           typedef typename _Hashtable::const_local_iterator const_local_iterator;
                                                             ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:125:47: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           typedef typename _Hashtable::size_type  size_type;
                                                   ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:126:52: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           typedef typename _Hashtable::difference_type difference_type;
                                                        ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:280:7: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           operator=(initializer_list<value_type> __l)
           ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:379:2: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
      emplace(_Args&&... __args)
      ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:432:7: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           insert(const value_type& __x)
           ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:439:2: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
      insert(_Pair&& __x)
      ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:499:7: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           insert(initializer_list<value_type> __l)
           ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:645:7: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           equal_range(const key_type& __x)
           ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:649:7: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           equal_range(const key_type& __x) const
           ^
    [GCC/Rust]/gcc/rust/parse/rust-parse.cc: In function 'bool Rust::peculiar_fragment_match_compatible(Rust::AST::MacroMatchFragment&, Rust::AST::MacroMatch&)':
    [GCC/Rust]/gcc/rust/parse/rust-parse.cc:104:5: error: too many initializers for 'std::unordered_map<Rust::AST::MacroFragSpec::Kind, std::vector<Rust::TokenId> >'
         };
         ^
    [GCC/Rust]/gcc/rust/parse/rust-parse.cc:119:16: error: no match for 'operator[]' (operand types are 'std::unordered_map<Rust::AST::MacroFragSpec::Kind, std::vector<Rust::TokenId> >' and 'Rust::AST::MacroFragSpec::Kind')
        = follow_set[last_match.get_frag_spec ().get_kind ()];
                    ^
    make[2]: *** [[GCC/Rust]/gcc/rust/Make-lang.in:299: rust/rust-parse.o] Error 1


Co-authored-by: Thomas Schwinge <thomas@codesourcery.com>
2022-03-23 21:07:53 +00:00
Thomas Schwinge 7af3505c97 For use as 'std::unordered_map' key, provide 'std::hash' for 'Rust::AST::MacroFragSpec::Kind' enum class
... recently introduced in #1044 commit 35ca685200
"macros: Add base functions to check for follow-set ambiguities".

Otherwise, at least with an oldish GCC 5.2, compilation of
'gcc/rust/parse/rust-parse.cc' fails noisily:

    In file included from [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/hashtable.h:35:0,
                     from [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/unordered_map:47,
                     from [GCC/Rust]/gcc/rust/rust-system.h:46,
                     from [GCC/Rust]/gcc/rust/rust-linemap.h:12,
                     from [GCC/Rust]/gcc/rust/lex/rust-lex.h:22,
                     from [GCC/Rust]/gcc/rust/parse/rust-parse.h:20,
                     from [GCC/Rust]/gcc/rust/parse/rust-parse.cc:17:
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/hashtable_policy.h: In instantiation of 'struct std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> >':
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/type_traits:137:12:   required from 'struct std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > >'
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/type_traits:148:38:   required from 'struct std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h💯66:   required from 'class std::unordered_map<Rust::AST::MacroFragSpec::Kind, std::vector<Rust::TokenId> >'
    [GCC/Rust]/gcc/rust/parse/rust-parse.cc:101:5:   required from here
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/hashtable_policy.h:85:34: error: no match for call to '(const std::hash<Rust::AST::MacroFragSpec::Kind>) (const Rust::AST::MacroFragSpec::Kind&)'
      noexcept(declval<const _Hash&>()(declval<const _Key&>()))>
                                      ^
    In file included from [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/move.h:57:0,
                     from [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/stl_pair.h:59,
                     from [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/stl_algobase.h:64,
                     from [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/char_traits.h:39,
                     from [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/string:40,
                     from [GCC/Rust]/gcc/rust/rust-system.h:34,
                     from [GCC/Rust]/gcc/rust/rust-linemap.h:12,
                     from [GCC/Rust]/gcc/rust/lex/rust-lex.h:22,
                     from [GCC/Rust]/gcc/rust/parse/rust-parse.h:20,
                     from [GCC/Rust]/gcc/rust/parse/rust-parse.cc:17:
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/type_traits: In instantiation of 'struct std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >':
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h💯66:   required from 'class std::unordered_map<Rust::AST::MacroFragSpec::Kind, std::vector<Rust::TokenId> >'
    [GCC/Rust]/gcc/rust/parse/rust-parse.cc:101:5:   required from here
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/type_traits:148:38: error: 'value' is not a member of 'std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > >'
         : public integral_constant<bool, !_Pp::value>
                                          ^
    In file included from [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/unordered_map:48:0,
                     from [GCC/Rust]/gcc/rust/rust-system.h:46,
                     from [GCC/Rust]/gcc/rust/rust-linemap.h:12,
                     from [GCC/Rust]/gcc/rust/lex/rust-lex.h:22,
                     from [GCC/Rust]/gcc/rust/parse/rust-parse.h:20,
                     from [GCC/Rust]/gcc/rust/parse/rust-parse.cc:17:
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h: In instantiation of 'class std::unordered_map<Rust::AST::MacroFragSpec::Kind, std::vector<Rust::TokenId> >':
    [GCC/Rust]/gcc/rust/parse/rust-parse.cc:101:5:   required from here
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h💯66: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           typedef __umap_hashtable<_Key, _Tp, _Hash, _Pred, _Alloc>  _Hashtable;
                                                                      ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:107:45: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           typedef typename _Hashtable::key_type key_type;
                                                 ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:108:47: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           typedef typename _Hashtable::value_type value_type;
                                                   ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:109:48: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           typedef typename _Hashtable::mapped_type mapped_type;
                                                    ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:110:43: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           typedef typename _Hashtable::hasher hasher;
                                               ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:111:46: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           typedef typename _Hashtable::key_equal key_equal;
                                                  ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:112:51: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           typedef typename _Hashtable::allocator_type allocator_type;
                                                       ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:117:45: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           typedef typename _Hashtable::pointer  pointer;
                                                 ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:118:50: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           typedef typename _Hashtable::const_pointer const_pointer;
                                                      ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:119:47: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           typedef typename _Hashtable::reference  reference;
                                                   ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:120:52: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           typedef typename _Hashtable::const_reference const_reference;
                                                        ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:121:46: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           typedef typename _Hashtable::iterator  iterator;
                                                  ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:122:51: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           typedef typename _Hashtable::const_iterator const_iterator;
                                                       ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:123:51: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           typedef typename _Hashtable::local_iterator local_iterator;
                                                       ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:124:57: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           typedef typename _Hashtable::const_local_iterator const_local_iterator;
                                                             ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:125:47: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           typedef typename _Hashtable::size_type  size_type;
                                                   ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:126:52: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           typedef typename _Hashtable::difference_type difference_type;
                                                        ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:280:7: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           operator=(initializer_list<value_type> __l)
           ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:379:2: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
      emplace(_Args&&... __args)
      ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:432:7: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           insert(const value_type& __x)
           ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:439:2: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
      insert(_Pair&& __x)
      ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:499:7: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           insert(initializer_list<value_type> __l)
           ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:645:7: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           equal_range(const key_type& __x)
           ^
    [GCC]/i686-pc-linux-gnu/include/c++/5.2.0/bits/unordered_map.h:649:7: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<std::hash<Rust::AST::MacroFragSpec::Kind> >, std::__detail::__is_noexcept_hash<Rust::AST::MacroFragSpec::Kind, std::hash<Rust::AST::MacroFragSpec::Kind> > > >'
           equal_range(const key_type& __x) const
           ^
    [GCC/Rust]/gcc/rust/parse/rust-parse.cc: In function 'bool Rust::peculiar_fragment_match_compatible(Rust::AST::MacroMatchFragment&, Rust::AST::MacroMatch&)':
    [GCC/Rust]/gcc/rust/parse/rust-parse.cc:104:5: error: too many initializers for 'std::unordered_map<Rust::AST::MacroFragSpec::Kind, std::vector<Rust::TokenId> >'
         };
         ^
    [GCC/Rust]/gcc/rust/parse/rust-parse.cc:119:16: error: no match for 'operator[]' (operand types are 'std::unordered_map<Rust::AST::MacroFragSpec::Kind, std::vector<Rust::TokenId> >' and 'Rust::AST::MacroFragSpec::Kind')
        = follow_set[last_match.get_frag_spec ().get_kind ()];
                    ^
    make[2]: *** [[GCC/Rust]/gcc/rust/Make-lang.in:299: rust/rust-parse.o] Error 1
2022-03-23 21:58:13 +01:00
Thomas Schwinge 85ffe83ad7 Fix '#include <algorithm>' [#159]
... recently introduced in #1044 commit 35ca685200
"macros: Add base functions to check for follow-set ambiguities".

GCC doesn't like that:

    In file included from [...]
    ./mm_malloc.h:42:12: error: attempt to use poisoned "malloc"
         return malloc (__size);
                ^

See commit e7b3f654f2, for example.
2022-03-23 18:36:52 +01:00
Arthur Cohen 6821a642ab macros: Add remaining restrictions for follow-set restrictions
Adds the remaining restrictions for follow-set ambiguities in macros.
This means adding the remaining allowed tokens for all fragment
specifiers with follow-up restrictions, as well as handling allowed
fragment specifiers in certain cases. For example, :vis specifiers can
sometimes be followed by fragments, if they have the :ident, :ty or
:path specifier. Likewise for :path and :ty which can be followed by a
:block.

Finally, we also allow *any* fragment after a matcher: Since the matcher
is delimiter by parentheses, brackets or curlies, anything is allowed
afterwards.
2022-03-23 14:35:47 +01:00
bors[bot] eef1ee2638
Merge #1049
1049: Add better restrictions around semicolons in statements r=CohenArthur a=CohenArthur

When parsing macro invocations, rustc does not actually consume the
statement's trailing semicolon.

Let's take the following example:
```rust
macro_rules! one_stmt {
    ($s:stmt) => {};
}

macro_rules! one_or_more_stmt {
    ($($s:stmt)*) => {};
}

one_stmt!(let a = 1);
one_stmt!(let b = 2;); // error

one_or_more_stmt!(;); // valid
one_or_more_stmt!(let a = 15;); // valid, two statements!
one_or_more_stmt!(let a = 15 let b = 13); // valid, two statements again
```

A semicolon can count as a valid empty statement, but cannot be part of
a statement (in macro invocations). This commit adds more restrictions
that allow the parser to not always expect a semicolon token after the
statement. Furthermore, this fixes a test that was previously accepted
by the compiler but not by rustc.

Fixes #1046 

Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
2022-03-23 09:28:09 +00:00
bors[bot] b9720caa10
Merge #1044
1044: Restrict follow-up tokens on `expr` and `stmt` r=CohenArthur a=CohenArthur

This adds a base for respecting the [Macro Follow-Set Ambiguity specification](https://doc.rust-lang.org/reference/macro-ambiguity.html).

If the design is validated, adding more restrictions on other fragment specifiers should not be difficult

Addresses #947 

Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
2022-03-23 09:00:05 +00:00
Arthur Cohen 35ca685200 macros: Add base functions to check for follow-set ambiguities
Rust does not allow for all macro fragments to be followed by any kind
of tokens: We must check tokens following those fragments that might
contain restrictions and make sure that they are allowed, conforming to
the Macro Follow-Set Ambiguity specification

Co-authored-by: philberty <philip.herron@embecosm.com>

macro-frag-spec: Transform enum into a class

This allows us to add methods on the fragment specifier, which are
needed to make sure that follow-set ambiguities are respected

tests: Add tests for forbidden follow-up tokens

This also fix a test that was previously accepted but invalid: rustc
also rejected it
2022-03-23 09:56:23 +01:00
bors[bot] 1d34c120c4
Merge #1026
1026: Enable -Werror r=tschwinge a=CastilloDel



Fixes #694 

- \[x] GCC development requires copyright assignment or the Developer's Certificate of Origin sign-off, see https://gcc.gnu.org/contribute.html or https://gcc.gnu.org/dco.html
- \[x] Read contributing guidelines
- \[ ] `make check-rust` passes locally
- \[ ] Run `clang-format`
- \[ ] Added any relevant test cases to `gcc/testsuite/rust/`

The last three ones shouldn't be necessary for this change.

---

Update the CI to use the bootstrap build process and enable -Werror

Signed-off-by: Daniel del Castillo <delcastillodelarosadaniel@gmail.com>

Co-authored-by: CastilloDel <delcastillodelarosadaniel@gmail.com>
Co-authored-by: Thomas Schwinge <thomas@codesourcery.com>
2022-03-22 21:58:02 +00:00
bors[bot] fb886737e2
Merge #1047
1047: Add helper debugging function for substituted tokens r=CohenArthur a=CohenArthur

Since this is less noisy, I guess we can keep it in at all times instead
of commenting it. Doing it like so - through a single function call -
means that we avoid creating the string entirely in release builds

Fixes #967 

Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
2022-03-22 20:57:05 +00:00
Arthur Cohen ef56381862 parser: Add better restrictions around semicolons in statements
When parsing macro invocations, rustc does not actually consume the
statement's trailing semicolon.

Let's take the following example:
```rust
macro_rules! one_stmt {
    ($s:stmt) => {};
}

macro_rules! one_or_more_stmt {
    ($($s:stmt)*) => {};
}

one_stmt!(let a = 1);
one_stmt!(let b = 2;); // error

one_or_more_stmt!(;); // valid
one_or_more_stmt!(let a = 15;); // valid, two statements!
one_or_more_stmt!(let a = 15 let b = 13); // valid, two statements again
```

A semicolon can count as a valid empty statement, but cannot be part of
a statement (in macro invocations). This commit adds more restrictions
that allow the parser to not always expect a semicolon token after the
statement. Furthermore, this fixes a test that was previously accepted
by the compiler but not by rustc.
2022-03-22 16:00:30 +01:00
Thomas Schwinge f0b5ac2e82 Document 'Continuous Integration', 'Compiler Diagnostics' in 'README.md' 2022-03-22 14:51:53 +01:00
bors[bot] cc6e405912
Merge #1041
1041: macros: Only expand merged repetitions if they contain the same amount r=CohenArthur a=CohenArthur

Depends on #1040 
Fixes #948 

Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
2022-03-22 11:30:04 +00:00
Thomas Schwinge f91f637652 Tune '.github/workflows/ccpp.yml:jobs.build-and-check', 'Check for new warnings' step
Run it in scratch directory, too, to not pollute the pristine sources
directory.  Point to <https://github.com/Rust-GCC/gccrs/pull/1026> in case of
failure.
2022-03-22 12:17:23 +01:00
Thomas Schwinge 10ff5d5507 Merge 'Build logs' into 'Build' in '.github/workflows/ccpp.yml:jobs.build-and-check'
This avoids the supposed issue that in case that 'make' fails, the whole
'jobs.build-and-check' stops, and 'Build logs' isn't executed, and thus there's
no indication in the GitHub UI why 'make' failed.

Using a shell pipeline is OK; the exit code of 'make' isn't lost, as per
<https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsshell>,
'bash' is being run with '-o pipefail'.
2022-03-22 12:17:23 +01:00
Thomas Schwinge 246fb48cbb Force 'LC_ALL=C.UTF-8' for all steps of '.github/workflows/ccpp.yml:jobs.build-and-check'
That's what I use in my local development enviroment, and I suppose I'll
be the main one touching this file semi-regularly in context of
<https://github.com/Rust-GCC/gccrs/issues/247> "Rebasing against GCC".
2022-03-22 12:17:23 +01:00
bors[bot] 6ecd43c779
Merge #1040
1040: Do not propagate parse errors in match repetitions r=CohenArthur a=CohenArthur

Since parsing repetitions is very eager, the parser might accumulate
bogus errors by trying to match more repetitions than there are. We can
avoid this by clearing the parsing errors if parsing repetitions
returned a valid result. This should not be an issue for previous
matchers erroring out, as they would immediately return upon failure and
not reach inside other match functions.

We need to figure out the best way to emit parser errors, as we do not always want to emit them in `match_fragment`. I think for now the easiest is to just *not* emit parse errors and simply error out with "failed to match macro rule". We will need to think about adding a bunch of hints too in order to make using macros easier.

Fixes #958 

Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
2022-03-22 11:02:45 +00:00
Thomas Schwinge 202e61bc2d Force 'LC_ALL=C' for all steps of '.github/workflows/ccpp.yml:jobs.build-and-check' 2022-03-22 09:55:43 +01:00
Arthur Cohen 651d9a77ce macros: Add helper debugging function for substituted tokens
Since this is less noisy, I guess we can keep it in at all times instead
of commenting it. Doing it like so - through a single function call -
means that we avoid creating the string entirely in release builds

Co-authored-by: philberty <philip.herron@embecosm.com>
2022-03-21 16:52:31 +01:00
bors[bot] 32894e6986
Merge #1042
1042: Parse reserved keywords as valid fragments identifiers r=CohenArthur a=CohenArthur

Per the reference, macro fragments actually accept all identifiers, not
NON_KEYWORD_IDENTIFIERS

Fixes #1013 

Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
2022-03-21 12:41:52 +00:00
Philip Herron afa451b311 Add initial support for unsized method resolution
In order to support slices, we end up with an operator overload call of:

```
impl<T, I> Index<I> for [T]
where
    I: SliceIndex<[T]>,
{
    type Output = I::Output;

    fn index(&self, index: I) -> &I::Output {
        index.index(self)
    }
}
```

So this means the self in this case is an array[T,capacity] and the index parameter is of type Range<usize>. In order to actually call this method
which has a self parameter of [T] we need to be able to 'unsize' the array
into a slice.

Addresses #849
2022-03-21 12:40:20 +00:00
CastilloDel 60d1fd533c Add a check for new warnings to the CI
This should prevent new warnings from appearing silently

Signed-off-by: Daniel del Castillo delcastillodelarosadaniel@gmail.com
2022-03-20 09:42:41 +00:00
Arthur Cohen 80d9690242 parser: Parse reserved keywords as valid fragments identifiers
Per the reference, macro fragments actually accept all identifiers, not
NON_KEYWORD_IDENTIFIERS
2022-03-18 14:44:29 +01:00
Arthur Cohen f8c550f7e1 macros: Only expand merged repetitions if they contain the same amount
of matches

Forbid merging repetitions if the matched fragments do not contain the
same amount of repetitions
2022-03-18 14:09:03 +01:00
Arthur Cohen a64a5cf77c macros: Do not propagate parse errors in match repetitions
Since parsing repetitions is very eager, the parser might accumulate
bogus errors by trying to match more repetitions than there are. We can
avoid this by clearing the parsing errors if parsing repetitions
returned a valid result. This should not be an issue for previous
matchers erroring out, as they would immediately return upon failure and
not reach inside other match functions.
2022-03-18 12:40:05 +01:00
bors[bot] 1bb9a29688
Merge #1029
1029: Macro in trait impl r=CohenArthur a=CohenArthur

Needs #1028 

You can just review the last commit to avoid reviewing twice. Sorry about that!

Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
2022-03-17 16:04:23 +00:00
Arthur Cohen a7ef6f98be macros: Allow macro calls in trait implementations
Just like inherent implementation blocks, trait implementation blocks
(`impl Trait for Type`) can also contain macro invocations.
2022-03-17 15:56:18 +01:00
Arthur Cohen 935b561e7f macros: Add test cases for remaining expansion contexts 2022-03-17 15:51:09 +01:00
Arthur Cohen 1a2ef9cae9 macros: Add remaining context and improve parsing macro dispatch
This allows us to expand macor invocations in more places, as macro
calls are not limited to statements or expressions. It is quite common
to use macros to abstract writing repetitive boilerplate for type
implementations, for example.
2022-03-17 15:51:06 +01:00
bors[bot] 1a14348afe
Merge #1035
1035: Handle -fsyntax-only r=CohenArthur a=CohenArthur

Handle the -fsyntax-only properly from the rust frontend. This flag
allows checking for syntax and stopping after that, skipping further
passes of the pipeline.
The flag was accepted by the frontend, but was not used anywhere.

Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
2022-03-17 13:15:45 +00:00
bors[bot] b7baee8795
Merge #1037
1037: Support placeholders becoming slices r=philberty a=philberty

When we setup trait-impls the type-alias are allowed to become any type
this interface was missing a visitor. We also need to support constraining
type-parameters behind slices.

The get_root interface is currently unsafe, it needs a flag for allowing
unsized and for keeping a map of adjustments along the way. This will
be added down the line when we support unsized method resolution.

Fixes #1034
Addresses #849 

Co-authored-by: Philip Herron <philip.herron@embecosm.com>
2022-03-17 12:47:18 +00:00