Skip to content

Commit 9d9c399

Browse files
committed
stash
1 parent 6b891ee commit 9d9c399

File tree

8 files changed

+181
-0
lines changed

8 files changed

+181
-0
lines changed

gcc/rust/Make-lang.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ GRS_OBJS = \
146146
rust/rust-finalize-imports-2.0.o \
147147
rust/rust-ice-finalizer.o \
148148
rust/rust-late-name-resolver-2.0.o \
149+
rust/rust-identifier-path.o \
149150
rust/rust-immutable-name-resolution-context.o \
150151
rust/rust-name-resolver.o \
151152
rust/rust-resolve-builtins.o \
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Copyright (C) 2026 Free Software Foundation, Inc.
2+
3+
// This file is part of GCC.
4+
5+
// GCC is free software; you can redistribute it and/or modify it under
6+
// the terms of the GNU General Public License as published by the Free
7+
// Software Foundation; either version 3, or (at your option) any later
8+
// version.
9+
10+
// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11+
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
12+
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13+
// for more details.
14+
15+
// You should have received a copy of the GNU General Public License
16+
// along with GCC; see the file COPYING3. If not see
17+
// <http://www.gnu.org/licenses/>.
18+
19+
#include "rust-system.h"
20+
#include "rust-identifier-path.h"
21+
#include "rust-pattern.h"
22+
23+
namespace Rust {
24+
namespace Resolver2_0 {
25+
26+
IdentifierPathPass::IdentifierPathPass (
27+
NameResolutionContext &ctx, std::map<Usage, Definition> expected_mappings)
28+
: ctx (&ctx), expected_mappings (std::move (expected_mappings))
29+
{}
30+
31+
void
32+
IdentifierPathPass::go (AST::Crate &crate, NameResolutionContext &ctx,
33+
std::map<Usage, Definition> expected_mappings)
34+
{
35+
IdentifierPathPass pass (ctx, std::move (expected_mappings));
36+
pass.visit (crate);
37+
}
38+
39+
void
40+
IdentifierPathPass::reseat (std::unique_ptr<AST::Pattern> &ptr)
41+
{
42+
AST::IdentifierPattern *ident_pat;
43+
if (ptr->get_pattern_kind () == AST::Pattern::Kind::Identifier)
44+
ident_pat = static_cast<AST::IdentifierPattern *> (ptr.get ());
45+
else
46+
return;
47+
48+
auto expected_it = expected_mappings.find (Usage (ident_pat->get_node_id ()));
49+
50+
if (expected_it != expected_mappings.end ())
51+
{
52+
auto def = expected_it->second;
53+
54+
std::vector<AST::PathExprSegment> segments;
55+
segments.emplace_back (ident_pat->get_ident ().as_string (),
56+
ident_pat->get_locus ());
57+
ctx->map_usage (Usage (segments.back ().get_node_id ()), def);
58+
ptr = std::make_unique<AST::PathInExpression> (
59+
std::move (segments), std::vector<AST::Attribute> (),
60+
ident_pat->get_locus ());
61+
ctx->map_usage (Usage (ptr->get_node_id ()), def);
62+
}
63+
}
64+
65+
} // namespace Resolver2_0
66+
} // namespace Rust
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Copyright (C) 2026 Free Software Foundation, Inc.
2+
3+
// This file is part of GCC.
4+
5+
// GCC is free software; you can redistribute it and/or modify it under
6+
// the terms of the GNU General Public License as published by the Free
7+
// Software Foundation; either version 3, or (at your option) any later
8+
// version.
9+
10+
// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11+
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
12+
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13+
// for more details.
14+
15+
// You should have received a copy of the GNU General Public License
16+
// along with GCC; see the file COPYING3. If not see
17+
// <http://www.gnu.org/licenses/>.
18+
19+
#ifndef RUST_RESOLVE_IDENTIFIER_PATH_H
20+
#define RUST_RESOLVE_IDENTIFIER_PATH_H
21+
22+
#include "rust-ast-pointer-visitor.h"
23+
#include "rust-name-resolution-context.h"
24+
25+
namespace Rust {
26+
namespace Resolver2_0 {
27+
28+
// changes IdentifierPattern instances to PathInExpression instances
29+
class IdentifierPathPass : public AST::PointerVisitor
30+
{
31+
public:
32+
IdentifierPathPass (NameResolutionContext &ctx,
33+
std::map<Usage, Definition> expected_mappings);
34+
35+
static void go (AST::Crate &crate, NameResolutionContext &ctx,
36+
std::map<Usage, Definition> expected_mappings);
37+
38+
using AST::PointerVisitor::reseat;
39+
40+
void reseat (std::unique_ptr<AST::Pattern> &ptr) override;
41+
42+
private:
43+
NameResolutionContext *ctx;
44+
std::map<Usage, Definition> expected_mappings;
45+
};
46+
47+
} // namespace Resolver2_0
48+
} // namespace Rust
49+
50+
#endif // ! RUST_RESOLVE_IDENTIFIER_PATH_H

gcc/rust/resolve/rust-late-name-resolver-2.0.cc

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "rust-hir-type-check.h"
3232
#include "rust-ice-finalizer.h"
3333
#include "rust-ast.h"
34+
#include "rust-identifier-path.h"
3435

3536
namespace Rust {
3637
namespace Resolver2_0 {
@@ -45,6 +46,8 @@ Late::go (AST::Crate &crate)
4546
Builtins::setup_type_ctx ();
4647

4748
visit (crate);
49+
50+
IdentifierPathPass::go (crate, ctx, std::move (expected_mappings));
4851
}
4952

5053
void
@@ -204,6 +207,28 @@ Late::visit (AST::IdentifierPattern &identifier)
204207
{
205208
DefaultResolver::visit (identifier);
206209

210+
// check if this is *really* a path pattern
211+
if (!identifier.get_is_ref () && !identifier.get_is_mut ()
212+
&& !identifier.has_subpattern ())
213+
{
214+
auto res = ctx.values.get (identifier.get_ident ());
215+
if (res)
216+
{
217+
rust_debug_loc (identifier.get_locus (), "RESOLVING %d to %d",
218+
(int) identifier.get_node_id (),
219+
(int) res->get_node_id ());
220+
if (res->is_ambiguous ())
221+
rust_error_at (identifier.get_locus (), ErrorCode::E0659,
222+
"%qs is ambiguous",
223+
identifier.get_ident ().as_string ().c_str ());
224+
else
225+
expected_mappings.insert (
226+
std::make_pair (Usage (identifier.get_node_id ()),
227+
Definition (res->get_node_id ())));
228+
return;
229+
}
230+
}
231+
207232
visit_identifier_as_pattern (ctx, identifier.get_ident (),
208233
identifier.get_locus (),
209234
identifier.get_node_id (),

gcc/rust/resolve/rust-late-name-resolver-2.0.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ class Late : public DefaultResolver
7979

8080
/* used to prevent "impl Self {}", "impl (Self, i32) {}", etc */
8181
bool block_big_self;
82+
83+
/* used to help conversion from IdentifierPattern to PathInExpression */
84+
std::map<Usage, Definition> expected_mappings;
8285
};
8386

8487
// TODO: Add missing mappings and data structures

gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,8 @@ TopLevel::visit (AST::TupleStruct &tuple_struct)
309309
void
310310
TopLevel::visit (AST::EnumItem &variant)
311311
{
312+
rust_debug_loc (variant.get_locus (), "ITEM %d",
313+
(int) variant.get_node_id ());
312314
insert_enum_variant_or_error_out (variant.get_identifier (), variant);
313315

314316
DefaultResolver::visit (variant);
@@ -317,6 +319,8 @@ TopLevel::visit (AST::EnumItem &variant)
317319
void
318320
TopLevel::visit (AST::EnumItemTuple &variant)
319321
{
322+
rust_debug_loc (variant.get_locus (), "ITEM %d",
323+
(int) variant.get_node_id ());
320324
insert_enum_variant_or_error_out (variant.get_identifier (), variant);
321325

322326
DefaultResolver::visit (variant);
@@ -325,6 +329,8 @@ TopLevel::visit (AST::EnumItemTuple &variant)
325329
void
326330
TopLevel::visit (AST::EnumItemStruct &variant)
327331
{
332+
rust_debug_loc (variant.get_locus (), "ITEM %d",
333+
(int) variant.get_node_id ());
328334
insert_enum_variant_or_error_out (variant.get_identifier (), variant);
329335

330336
DefaultResolver::visit (variant);
@@ -333,6 +339,8 @@ TopLevel::visit (AST::EnumItemStruct &variant)
333339
void
334340
TopLevel::visit (AST::EnumItemDiscriminant &variant)
335341
{
342+
rust_debug_loc (variant.get_locus (), "ITEM %d",
343+
(int) variant.get_node_id ());
336344
insert_or_error_out (variant.get_identifier (), variant, Namespace::Types);
337345

338346
DefaultResolver::visit (variant);

gcc/rust/typecheck/rust-hir-type-check-path.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,8 @@ TypeCheckExpr::resolve_root_path (HIR::PathInExpression &expr, size_t *offset,
335335
= mappings.lookup_hir_enumitem (ref);
336336
bool is_enum_item = enum_item_lookup.first != nullptr
337337
&& enum_item_lookup.second != nullptr;
338+
rust_debug_loc (mappings.lookup_location (ref), "is enum? %s",
339+
is_enum_item ? "yes" : "no");
338340
if (is_enum_item)
339341
{
340342
HirId expr_id = expr.get_mappings ().get_hirid ();
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// { dg-additional-options '-w' }
2+
#![no_core]
3+
4+
enum E {
5+
A,
6+
B,
7+
C
8+
}
9+
10+
fn main() -> i32 {
11+
use E::C;
12+
13+
let v1 = match E::A {
14+
C => 1,
15+
E::A => 0,
16+
E::B => 1
17+
};
18+
19+
let v2 = match E::A {
20+
B => 0,
21+
E::A => 1,
22+
C => 1
23+
};
24+
25+
v1 + v2
26+
}

0 commit comments

Comments
 (0)