1087: Use loop to initialize repeat arrays r=philberty a=dafaust
This PR changes how we compile initializers for arrays of repeating elements. I use the same approach outlined in the comments of the linked issue, with some tweaks. It is very similar to how the D language front-end compiles, the new function `Gcc_backend::array_initializer` is heavily inspired by the D front-end's `build_array_set`
This fixes the issue where the compiler tries to allocate a vec containing all elements of the array to be constructed, and therefore explodes on huge constructions (e.g. `let x = [0u8; 4 * 1024 * 1024 * 1024 * 1024]`)
However, we can only initialize non-const arrays in this way. For arrays in const contexts we must initialize them at compile time, and therefore continue using the old method.
Fixes: #1068 Co-authored-by: David Faust <david.faust@oracle.com>
David Faust [Thu, 7 Apr 2022 16:41:37 +0000 (09:41 -0700)]
Emit loop initializer for repeat arrays
This commit changes how arrays of repeating elements, e.g. [5; 12] are
compiled. Rather than create a constructor which explicitly initializes
each element to the given value (which causes compiler OOM for large
arrays), we emit instructions to allocate the array then initialize the
elements in a loop.
However, we can only take this approach outside of const contexts -
const arrays must still use the old approach.
bors[bot] [Thu, 31 Mar 2022 09:56:35 +0000 (09:56 +0000)]
Merge #1071
1071: Allow transcribing of zero nodes in certain cases r=CohenArthur a=CohenArthur
When expanding AST fragments containing multiple nodes, we must be aware
that some cases allow expanding zero or more nodes. Any macro
transcription that gets parsed as many nodes (ie any transcriber function that calls `parse_many`) needs to be able to parse zero of those nodes and still get expanded properly (basically, removed).
Previously, this would cause a failure to lower the macro invocation which would remain as a child instead of getting stripped/erased.
Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
Arthur Cohen [Tue, 29 Mar 2022 08:12:48 +0000 (10:12 +0200)]
macros: Allow transcribing of zero items
When expanding AST fragments containing multiple nodes, we must be aware
that some cases allow expanding zero or more nodes. Any macro
transcription that gets parsed as many nodes (ie any transcriber function that calls `parse_many`) needs to be able to parse zero of those nodes and still get expanded properly (basically, removed).
Previously, this would cause a failure to lower the macro invocation which would remain as a child instead of getting stripped/erased.
bors[bot] [Thu, 31 Mar 2022 08:28:42 +0000 (08:28 +0000)]
Merge #1069
1069: Handle macro invocations in type contexts r=CohenArthur a=CohenArthur
Closes #1067
This highlighted two issues where parsing types is not entirely correct, which I'll raise. The code necessary to handle macro invocations in these two places should already be implemented.
Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
Arthur Cohen [Mon, 28 Mar 2022 08:52:47 +0000 (10:52 +0200)]
macros: Expand macro invocation properly in type contexts
Macro invocations can be present where the language expects types. Thus,
we need to add a new type of parsing context, a new transcriber, as well
as a new way to extract types from the AST Fragments. This adds a lot of
"expansion places" in the attribute visitor, as types can be present in
a wide variety of constructs
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
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
CohenArthur [Sun, 27 Mar 2022 11:35:03 +0000 (13:35 +0200)]
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>
bors[bot] [Fri, 25 Mar 2022 10:23:43 +0000 (10:23 +0000)]
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>
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
Arthur Cohen [Wed, 23 Mar 2022 15:43:01 +0000 (16:43 +0100)]
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.
: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>
bors[bot] [Thu, 24 Mar 2022 15:58:07 +0000 (15:58 +0000)]
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>
Arthur Cohen [Thu, 24 Mar 2022 14:03:20 +0000 (15:03 +0100)]
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
Arthur Cohen [Wed, 23 Mar 2022 15:50:47 +0000 (16:50 +0100)]
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.
Arthur Cohen [Wed, 23 Mar 2022 14:10:30 +0000 (15:10 +0100)]
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.
Arthur Cohen [Thu, 24 Mar 2022 07:55:47 +0000 (08:55 +0100)]
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.
bors[bot] [Thu, 24 Mar 2022 09:34:19 +0000 (09:34 +0000)]
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>
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:100: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:100: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:100: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>
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:100: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:100: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:100: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
Arthur Cohen [Wed, 23 Mar 2022 10:06:26 +0000 (11:06 +0100)]
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.
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>
Arthur Cohen [Fri, 18 Mar 2022 15:20:47 +0000 (16:20 +0100)]
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
bors[bot] [Tue, 22 Mar 2022 21:58:02 +0000 (21:58 +0000)]
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>
bors[bot] [Tue, 22 Mar 2022 20:57:05 +0000 (20:57 +0000)]
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>
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.
Thomas Schwinge [Tue, 22 Mar 2022 09:41:26 +0000 (10:41 +0100)]
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.
Thomas Schwinge [Tue, 22 Mar 2022 09:29:21 +0000 (10:29 +0100)]
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'.
Thomas Schwinge [Tue, 22 Mar 2022 09:25:29 +0000 (10:25 +0100)]
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".
bors[bot] [Tue, 22 Mar 2022 11:02:45 +0000 (11:02 +0000)]
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>
Arthur Cohen [Mon, 21 Mar 2022 15:52:31 +0000 (16:52 +0100)]
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
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.
Arthur Cohen [Fri, 18 Mar 2022 10:34:39 +0000 (11:34 +0100)]
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.
Arthur Cohen [Mon, 14 Mar 2022 16:08:07 +0000 (17:08 +0100)]
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.
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>
bors[bot] [Thu, 17 Mar 2022 12:47:18 +0000 (12:47 +0000)]
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>
Arthur Cohen [Thu, 17 Mar 2022 10:40:42 +0000 (11:40 +0100)]
parser: Handle -fsyntax-only properly
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.
bors[bot] [Thu, 17 Mar 2022 11:25:48 +0000 (11:25 +0000)]
Merge #1027 #1032
1027: parser: Allow parsing stmts without closing semicolon r=CohenArthur a=CohenArthur
In certain cases such as macro matching or macro expansion, it is
important to allow the parser to return a valid statement even if no
closing semicolon is given. This commit adds an optional parameter to
the concerned functions to allow a lack of semicolon those special cases
Closes #1011
Closes #1010
1032: Add AST kind information r=CohenArthur a=CohenArthur
Closes #1001
This PR adds a base for adding node information to our AST types. It can be used when requiring to differentiate between multiple kinds of nodes, while not necessarily wanting to do a full static cast. This will open up a lot of cleanup issues and good first issues for Project Pineapple
Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
Philip Herron [Thu, 17 Mar 2022 10:38:58 +0000 (10:38 +0000)]
Support placeholders becoming slices
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 commit fixes the issue reported in #391, but highlights another
one, which will be reported.
Closes #391
1033: Fix bad copy-paste in can equal interface for pointer types r=philberty a=philberty
When we perform method resolution we check if the self arguments can be
matched. Here the bug was that pointer types had a bad vistitor and only
could ever match reference types which is wrong and was a copy paste error.
Fixes #1031
Addresses #849
Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com> Co-authored-by: Philip Herron <philip.herron@embecosm.com>
This is a series of patches that were all required to fix this issue. We
now take advantage of our substitutions abstractions and traits
so that our TypeBoundPredicate's which form the basis of our HRTB code
I think this class is almost akin to rustc existential-trait-references. This now
reuses the same code path to give us the same error checking for generics
as we get with ADT's, functions etc.
With this refactoring in place we can then reuse the abstractions to map the
ID's from the used arguments in the type-bound-predicate, the impl block type
substation mappings and the self type itself.
There are quite a few cases to handle and our testsuite picked up all the regressions
so no behaviour of our existing test-cases have changed now. See each commit for
more detailed information.
Fixes #1019
Addresses #849
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
Philip Herron [Thu, 17 Mar 2022 09:44:46 +0000 (09:44 +0000)]
Fix bad copy-paste in can equal interface for pointer types
When we perform method resolution we check if the self arguments can be
matched. Here the bug was that pointer types had a bad vistitor and only
could ever match reference types which is wrong and was a copy paste error.
Arthur Cohen [Thu, 17 Mar 2022 09:21:32 +0000 (10:21 +0100)]
ast: Add base Node class with get_ast_kind() function
This adds a new base class common to all abstract base classes of the
AST: We can use it to store information shared by all nodes, such as the
newly introduced `AST::Kind` which helps in differentiating nodes.
We could also consider using it to store location info, since all AST
nodes probably need it.
bors[bot] [Thu, 17 Mar 2022 08:27:03 +0000 (08:27 +0000)]
Merge #1021
1021: macros: Do not try and re-expand if depth has exceeded recursion limit r=CohenArthur a=CohenArthur
We need to limit the amount of times that macro get expanded recursively
during macro-expansion. This limits the amount of times an ASTFragment
can be visited by simply incrementing the depth when setting a fragment,
and decreasing it when taking one. This way, recursive expansion which
happens at the expansion level (instead of the matching level) will
still get caught
Fixes #1012
Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
Philip Herron [Wed, 16 Mar 2022 16:19:31 +0000 (16:19 +0000)]
Fix unconstrained type parameter checks
This patch removes our old method of checking for unconstrained type
parameters which only worked for the basic cases such as:
impl<T> Foo { }
But checking for unconstrained types is more complex, we need to handle
covariant types such as:
impl<T> *T { }
Or
struct foo<X,Y>(X,Y);
impl<T> foo<&T,*T> {}
This rewrites the algorithm to take advantage of our substition
abstractions and HirIds so we can map the ids of the type-params to be
constrained and look at the trait-references used-arguments when the
generics are applied (or they may be empty) and then do the same for any
used arguments on an algebraic data type.
Philip Herron [Wed, 16 Mar 2022 15:22:52 +0000 (15:22 +0000)]
Make TypeBoundPredicate a subclass of the SubstitutionRef
This will allow us to reuse our generic substitions code to manage generic
traits and their substitions better. It will unify the handling in one
path so we get the same error handling.
Philip Herron [Wed, 16 Mar 2022 14:34:26 +0000 (14:34 +0000)]
Keep track of substitution mappings as part of the TraitReference
The TraitReference wrapper is a class that allows us to work with traits
in a query manar. This patch allows us to keep track of the substitution
mappings that are defined on the trait. This will always be non-empty
since traits always contain an implicit Self type parameter so there
is special handling in how we perform monomorphization.
Philip Herron [Mon, 14 Mar 2022 17:35:57 +0000 (17:35 +0000)]
Refactor TypeBoundPredicate to be below the definition for SubstitutionRef
This means TypeBoundPredicate will now be able to inherit all behaviours
of normal generics so we do not duplicate the work in handling generics
it will also allow us to more easily check for unconstrained type
parameters on traits.
Arthur Cohen [Mon, 14 Mar 2022 13:29:58 +0000 (14:29 +0100)]
parser: Allow parsing stmts without closing semicolon
In certain cases such as macro matching or macro expansion, it is
important to allow the parser to return a valid statement even if no
closing semicolon is given. This commit adds an optional parameter to
the concerned functions to allow a lack of semicolon those special cases
bors[bot] [Mon, 14 Mar 2022 15:03:08 +0000 (15:03 +0000)]
Merge #1025
1025: Fix memory corruption in generation of builtin functions r=philberty a=philberty
This patch removes the pop_fn calls since no fncontext stack is required here for these intrinsic.
More context on the issues is in the commit message.
Fixes #1024
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
Philip Herron [Mon, 14 Mar 2022 12:53:10 +0000 (12:53 +0000)]
Fix memory corruption in generation of builtin functions
When we compile normal language functions we maintain a stack of the
current function declaration and associated return addresses. This is used
while building up the GCC tree graph. When we generate builtin intrinsic
functions such as offset or size_of were missing their associated push_fn
but still performed a pop_fn on completion this resulted in a corrupt
stack which valgrind shown as bad read/writes.
This patch removes the pop_fn calls since no fncontext stack is required here for these intrinsics.
Arthur Cohen [Mon, 14 Mar 2022 09:36:09 +0000 (10:36 +0100)]
macros: Do not try and re-expand if depth has exceeded recursion limit
We need to limit the amount of times that macro get expanded recursively
during macro-expansion. This limits the amount of times an ASTFragment
can be visited by simply incrementing the depth when setting a fragment,
and decreasing it when taking one. This way, recursive expansion which
happens at the expansion level (instead of the matching level) will
still get caught
Fixes issue #979
1) Added the column!() macro using the LOCATION_COLUMN() from gcc_linemap
2) To-Do: add relevant test cases.
Signed-off-by : M V V S Manoj Kumar <mvvsmanojkumar@gmail.com>
The test case I added always fails, I can't figure out whether there is a problem in my test case or there is something wrong with my implementation of the column!() macro. Do let me know where I am going wrong and also if I missed something . :)
Co-authored-by: M V V S Manoj Kumar <mvvsmanojkumar@gmail.com>
Philip Herron [Fri, 11 Mar 2022 11:22:07 +0000 (11:22 +0000)]
Add code generation for the slice type
This type must respect the layout of the FatPtr type in libcore. Rust
implements slices using Rustc types in libcore and uses a neat trick.
The slice is generated into the FatPtr which contains the pointer and
length of the slice. This is then placed into a union called Repr which
has 3 variants a mutable and immutable pointer to the FatPtr and a final
variant which is the raw FatPtr. This means we can use unsafe access to
the union to gain a pointer to the FatPtr.