@@ -33,7 +33,8 @@ BindingLayer::bind_test (Identifier ident, Binding::Kind kind)
3333{
3434 for (auto &bind : bindings)
3535 {
36- if (bind.set .find (ident) != bind.set .cend () && bind.kind == kind)
36+ if (bind.idents .find (ident.as_string ()) != bind.idents .cend ()
37+ && bind.kind == kind)
3738 {
3839 return true ;
3940 }
@@ -60,20 +61,66 @@ BindingLayer::is_or_bound (Identifier ident)
6061}
6162
6263void
63- BindingLayer::insert_ident (Identifier ident)
64+ BindingLayer::insert_ident (std::string ident, location_t locus, bool is_ref,
65+ bool is_mut)
6466{
65- bindings.back ().set .insert (ident);
67+ bindings.back ().idents .emplace (
68+ std::move (ident), std::make_pair (locus, IdentifierMode (is_ref, is_mut)));
6669}
6770
6871void
6972BindingLayer::merge ()
7073{
71- auto last_binding = bindings.back ();
74+ auto last_binding = std::move ( bindings.back () );
7275 bindings.pop_back ();
73- for (auto &value : last_binding.set )
76+
77+ if (bindings.back ().has_expected_bindings )
7478 {
75- bindings.back ().set .insert (value);
79+ for (auto &value : bindings.back ().idents )
80+ {
81+ auto ident = value.first ;
82+ if (last_binding.idents .find (ident) == last_binding.idents .end ())
83+ {
84+ location_t locus = value.second .first ;
85+ rust_error_at (locus, ErrorCode::E0408 ,
86+ " variable %qs is not bound in all patterns" ,
87+ ident.c_str ());
88+ }
89+ }
7690 }
91+
92+ for (auto &value : last_binding.idents )
93+ {
94+ auto res = bindings.back ().idents .emplace (value);
95+ if (res.second )
96+ {
97+ if (bindings.back ().has_expected_bindings )
98+ {
99+ auto &ident = value.first ;
100+ location_t locus = value.second .first ;
101+ rust_error_at (locus, ErrorCode::E0408 ,
102+ " variable %qs is not bound in all patterns" ,
103+ ident.c_str ());
104+ }
105+ }
106+ else
107+ {
108+ auto this_mode = value.second .second ;
109+ auto other_mode = res.first ->second .second ;
110+ if (this_mode != other_mode)
111+ {
112+ auto &ident = value.first ;
113+ location_t locus = value.second .first ;
114+ rust_error_at (locus, ErrorCode::E0409 ,
115+ " variable %qs is bound inconsistently across "
116+ " pattern alternatives" ,
117+ ident.c_str ());
118+ }
119+ }
120+ }
121+
122+ if (bindings.back ().kind == Binding::Kind::Or)
123+ bindings.back ().has_expected_bindings = true ;
77124}
78125
79126BindingSource
0 commit comments