Skip to content

Commit 5fa17a3

Browse files
committed
stash
1 parent 21aaaa4 commit 5fa17a3

15 files changed

+218
-11
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 \

gcc/rust/checks/errors/rust-hir-pattern-analysis.cc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -936,7 +936,9 @@ PlaceInfo::specialize (const Constructor &c) const
936936
TyTy::VariantDef *variant
937937
= adt->get_variants ().at (c.get_variant_index ());
938938
if (variant->get_variant_type ()
939-
== TyTy::VariantDef::VariantType::NUM)
939+
== TyTy::VariantDef::VariantType::NUM
940+
|| variant->get_variant_type ()
941+
== TyTy::VariantDef::VariantType::UNIT)
940942
return {};
941943

942944
std::vector<PlaceInfo> new_place_infos;
@@ -1050,6 +1052,7 @@ WitnessPat::to_string () const
10501052

10511053
switch (variant->get_variant_type ())
10521054
{
1055+
case TyTy::VariantDef::VariantType::UNIT:
10531056
case TyTy::VariantDef::VariantType::NUM:
10541057
{
10551058
return buf;
@@ -1145,7 +1148,8 @@ WitnessMatrix::apply_constructor (const Constructor &ctor,
11451148
TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (ty);
11461149
TyTy::VariantDef *variant
11471150
= adt->get_variants ().at (ctor.get_variant_index ());
1148-
if (variant->get_variant_type () == TyTy::VariantDef::NUM)
1151+
if (variant->get_variant_type () == TyTy::VariantDef::NUM
1152+
|| variant->get_variant_type () == TyTy::VariantDef::UNIT)
11491153
arity = 0;
11501154
else
11511155
arity = variant->get_fields ().size ();

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "rust-attributes.h"
2828
#include "rust-finalize-imports-2.0.h"
2929
#include "rust-attribute-values.h"
30+
#include "rust-identifier-path.h"
3031

3132
namespace Rust {
3233
namespace Resolver2_0 {
@@ -70,6 +71,9 @@ Early::go (AST::Crate &crate)
7071
visit (crate);
7172

7273
textual_scope.pop ();
74+
75+
// handle IdentifierPattern vs PathInExpression disambiguation
76+
IdentifierPathPass::go (crate, ctx, std::move (ident_path_to_convert));
7377
}
7478

7579
bool
@@ -543,5 +547,29 @@ Early::visit (AST::UseTreeList &use_list)
543547
DefaultResolver::visit (use_list);
544548
}
545549

550+
void
551+
Early::visit (AST::IdentifierPattern &identifier)
552+
{
553+
// check if this is *really* a path pattern
554+
if (!identifier.get_is_ref () && !identifier.get_is_mut ()
555+
&& !identifier.has_subpattern ())
556+
{
557+
auto res = ctx.values.get (identifier.get_ident ());
558+
if (res)
559+
{
560+
if (res->is_ambiguous ())
561+
rust_error_at (identifier.get_locus (), ErrorCode::E0659,
562+
"%qs is ambiguous",
563+
identifier.get_ident ().as_string ().c_str ());
564+
else
565+
{
566+
// HACK: bail out if the definition is a function
567+
if (!ctx.mappings.is_function_node (res->get_node_id ()))
568+
ident_path_to_convert.insert (identifier.get_node_id ());
569+
}
570+
}
571+
}
572+
}
573+
546574
} // namespace Resolver2_0
547575
} // namespace Rust

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "rust-default-resolver.h"
2727
#include "rust-rib.h"
2828
#include "rust-toplevel-name-resolver-2.0.h"
29+
#include "rust-pattern.h"
2930

3031
namespace Rust {
3132
namespace Resolver2_0 {
@@ -67,6 +68,8 @@ class Early : public DefaultResolver
6768

6869
void visit (AST::Attribute &) override;
6970

71+
void visit (AST::IdentifierPattern &) override;
72+
7073
struct ImportData
7174
{
7275
enum class Kind
@@ -266,6 +269,9 @@ class Early : public DefaultResolver
266269
const Early::ImportPair &mapping);
267270

268271
void finalize_rebind_import (const Early::ImportPair &mapping);
272+
273+
/* used to help conversion from IdentifierPattern to PathInExpression */
274+
std::set<NodeId> ident_path_to_convert;
269275
};
270276

271277
} // namespace Resolver2_0
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
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 (NameResolutionContext &ctx,
27+
std::set<NodeId> ident_path_to_convert)
28+
: ctx (&ctx), ident_path_to_convert (std::move (ident_path_to_convert))
29+
{}
30+
31+
void
32+
IdentifierPathPass::go (AST::Crate &crate, NameResolutionContext &ctx,
33+
std::set<NodeId> ident_path_to_convert)
34+
{
35+
IdentifierPathPass pass (ctx, std::move (ident_path_to_convert));
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+
if (ident_path_to_convert.find (ident_pat->get_node_id ())
49+
!= ident_path_to_convert.end ())
50+
{
51+
std::vector<AST::PathExprSegment> segments;
52+
segments.emplace_back (ident_pat->get_ident ().as_string (),
53+
ident_pat->get_locus ());
54+
ptr = std::make_unique<AST::PathInExpression> (
55+
std::move (segments), std::vector<AST::Attribute> (),
56+
ident_pat->get_locus ());
57+
}
58+
}
59+
60+
} // namespace Resolver2_0
61+
} // 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::set<NodeId> ident_path_to_convert);
34+
35+
static void go (AST::Crate &crate, NameResolutionContext &ctx,
36+
std::set<NodeId> ident_path_to_convert);
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::set<NodeId> ident_path_to_convert;
45+
};
46+
47+
} // namespace Resolver2_0
48+
} // namespace Rust
49+
50+
#endif // ! RUST_RESOLVE_IDENTIFIER_PATH_H

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,8 @@ TopLevel::visit (AST::Function &function)
241241
insert_or_error_out (function.get_function_name (), function,
242242
Namespace::Values);
243243

244+
Analysis::Mappings::get ().add_function_node (function.get_node_id ());
245+
244246
DefaultResolver::visit (function);
245247
}
246248

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -283,13 +283,15 @@ TypeCheckItem::visit (HIR::StructStruct &struct_decl)
283283
RustIdent ident{path, struct_decl.get_locus ()};
284284

285285
// its a single variant ADT
286+
auto variant_type = struct_decl.is_unit_struct ()
287+
? TyTy::VariantDef::VariantType::UNIT
288+
: TyTy::VariantDef::VariantType::STRUCT;
286289
std::vector<TyTy::VariantDef *> variants;
287290
variants.push_back (
288291
new TyTy::VariantDef (struct_decl.get_mappings ().get_hirid (),
289292
struct_decl.get_mappings ().get_defid (),
290293
struct_decl.get_identifier ().as_string (), ident,
291-
TyTy::VariantDef::VariantType::STRUCT, tl::nullopt,
292-
std::move (fields)));
294+
variant_type, tl::nullopt, std::move (fields)));
293295

294296
// Process #[repr(X)] attribute, if any
295297
const AST::AttrVec &attrs = struct_decl.get_outer_attrs ();

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ TypeCheckPattern::visit (HIR::PathInExpression &pattern)
7373
HirId def_id = definition_id.value ();
7474

7575
tl::optional<HIR::Item *> hir_item = mappings.lookup_hir_item (def_id);
76-
// If the path refrerences an item, it must be constants or structs.
76+
// If the path references an item, it must be constants or structs.
7777
if (hir_item.has_value ())
7878
{
7979
HIR::Item *item = hir_item.value ();
@@ -127,7 +127,9 @@ TypeCheckPattern::visit (HIR::PathInExpression &pattern)
127127
rust_assert (ok);
128128
}
129129

130-
if (variant->get_variant_type () != TyTy::VariantDef::VariantType::NUM)
130+
if (variant->get_variant_type () != TyTy::VariantDef::VariantType::NUM
131+
&& variant->get_variant_type ()
132+
!= TyTy::VariantDef::VariantType::UNIT)
131133
{
132134
std::string variant_type = TyTy::VariantDef::variant_type_string (
133135
variant->get_variant_type ());

gcc/rust/typecheck/rust-tyty-variance-analysis.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,8 @@ GenericTyVisitorCtx::process_type (ADTType &ty)
241241

242242
for (const auto &variant : ty.get_variants ())
243243
{
244-
if (variant->get_variant_type () != VariantDef::NUM)
244+
if (variant->get_variant_type () != VariantDef::NUM
245+
&& variant->get_variant_type () != VariantDef::UNIT)
245246
{
246247
for (const auto &field : variant->get_fields ())
247248
add_constraints_from_ty (field->get_field_type (),

0 commit comments

Comments
 (0)