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.
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.
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>
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>
... 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
... 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.
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.
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>
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>
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
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>
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>
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.
1041: macros: Only expand merged repetitions if they contain the same amount r=CohenArthur a=CohenArthur
Depends on #1040Fixes#948
Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
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'.
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".
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>
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>
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>
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
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.
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>
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.
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>
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>
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: philberty <philip.herron@embecosm.com>
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#1011Closes#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>
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.
Fixes#1034
1022: attribute expansion: Fix spurious stripping of tail expression r=CohenArthur a=CohenArthur
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>
1030: Rewrite our unconstrained type-param error checking r=philberty a=philberty
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>
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
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.
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>
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.
Fixes#1019
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.
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.
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.