Skip to content

Commit 457a44e

Browse files
CohenArthurP-E-P
authored andcommitted
nr: Add proper prelude resolution and fill it upon encountering a prelude.
gcc/rust/ChangeLog: * ast/rust-ast.h: Add Type::Kind. * ast/rust-macro.h: Use it. * ast/rust-path.h: Likewise. * ast/rust-type.h: Likewise. * resolve/rust-default-resolver.cc (is_lang_impl): New method. (DefaultResolver::visit): Collect lang item implementations in the prelude. * resolve/rust-forever-stack.h: Add new method for lang prelude injection. * resolve/rust-forever-stack.hxx: Define it. * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Identifier patterns can resolve to empty structs or variants. * resolve/rust-name-resolution-context.h: Improve resolution.
1 parent 49d6814 commit 457a44e

File tree

9 files changed

+144
-9
lines changed

9 files changed

+144
-9
lines changed

gcc/rust/ast/rust-ast.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1450,6 +1450,28 @@ class TraitBound;
14501450
class Type : public Visitable
14511451
{
14521452
public:
1453+
enum Kind
1454+
{
1455+
MacroInvocation,
1456+
TypePath,
1457+
QualifiedPathInType,
1458+
ImplTrait,
1459+
TraitObject,
1460+
Parenthesised,
1461+
ImplTraitTypeOneBound,
1462+
TraitObjectTypeOneBound,
1463+
Tuple,
1464+
Never,
1465+
RawPointer,
1466+
Reference,
1467+
Array,
1468+
Slice,
1469+
Inferred,
1470+
BareFunction,
1471+
};
1472+
1473+
virtual Kind get_type_kind () const = 0;
1474+
14531475
// Unique pointer custom clone function
14541476
std::unique_ptr<Type> clone_type () const
14551477
{

gcc/rust/ast/rust-macro.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,11 @@ class MacroInvocation : public TypeNoBounds,
818818
return Item::Kind::MacroInvocation;
819819
}
820820

821+
Type::Kind get_type_kind () const override
822+
{
823+
return Type::Kind::MacroInvocation;
824+
}
825+
821826
protected:
822827
Item *clone_item_impl () const override
823828
{

gcc/rust/ast/rust-path.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1273,6 +1273,8 @@ class TypePath : public TypeNoBounds
12731273
}
12741274

12751275
size_t get_num_segments () const { return segments.size (); }
1276+
1277+
Type::Kind get_type_kind () const override { return Type::Kind::TypePath; }
12761278
};
12771279

12781280
struct QualifiedPathType
@@ -1558,6 +1560,11 @@ class QualifiedPathInType : public TypeNoBounds
15581560
}
15591561

15601562
location_t get_locus () const override final { return locus; }
1563+
1564+
Type::Kind get_type_kind () const override
1565+
{
1566+
return Type::Kind::QualifiedPathInType;
1567+
}
15611568
};
15621569
} // namespace AST
15631570
} // namespace Rust

gcc/rust/ast/rust-type.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,8 @@ class ImplTraitType : public Type
186186
{
187187
return type_param_bounds;
188188
}
189+
190+
Type::Kind get_type_kind () const override { return Type::Kind::ImplTrait; }
189191
};
190192

191193
// An opaque value of another type that implements a set of traits
@@ -258,6 +260,8 @@ class TraitObjectType : public Type
258260
{
259261
return type_param_bounds;
260262
}
263+
264+
Type::Kind get_type_kind () const override { return Type::Kind::TraitObject; }
261265
};
262266

263267
// A type with parentheses around it, used to avoid ambiguity.
@@ -326,6 +330,11 @@ class ParenthesisedType : public TypeNoBounds
326330
rust_assert (type_in_parens != nullptr);
327331
return type_in_parens;
328332
}
333+
334+
Type::Kind get_type_kind () const override
335+
{
336+
return Type::Kind::Parenthesised;
337+
}
329338
};
330339

331340
// Impl trait with a single bound? Poor reference material here.
@@ -361,6 +370,11 @@ class ImplTraitTypeOneBound : public TypeNoBounds
361370
{
362371
return new ImplTraitTypeOneBound (trait_bound->reconstruct (), locus);
363372
}
373+
374+
Type::Kind get_type_kind () const override
375+
{
376+
return Type::Kind::ImplTraitTypeOneBound;
377+
}
364378
};
365379

366380
/* A trait object with a single trait bound. The "trait bound" is really just
@@ -412,6 +426,11 @@ class TraitObjectTypeOneBound : public TypeNoBounds
412426
}
413427

414428
bool is_dyn () const { return has_dyn; }
429+
430+
Type::Kind get_type_kind () const override
431+
{
432+
return Type::Kind::TraitObjectTypeOneBound;
433+
}
415434
};
416435

417436
class TypePath; // definition moved to "rust-path.h"
@@ -478,6 +497,8 @@ class TupleType : public TypeNoBounds
478497
{
479498
return new TupleType (reconstruct_vec (elems), locus);
480499
}
500+
501+
Type::Kind get_type_kind () const override { return Type::Kind::Tuple; }
481502
};
482503

483504
/* A type with no values, representing the result of computations that never
@@ -507,6 +528,8 @@ class NeverType : public TypeNoBounds
507528
location_t get_locus () const override final { return locus; }
508529

509530
void accept_vis (ASTVisitor &vis) override;
531+
532+
Type::Kind get_type_kind () const override { return Type::Kind::Never; }
510533
};
511534

512535
// A type consisting of a pointer without safety or liveness guarantees
@@ -588,6 +611,8 @@ class RawPointerType : public TypeNoBounds
588611
{
589612
return new RawPointerType (pointer_type, type->reconstruct (), locus);
590613
}
614+
615+
Type::Kind get_type_kind () const override { return Type::Kind::RawPointer; }
591616
};
592617

593618
// A type pointing to memory owned by another value
@@ -682,6 +707,8 @@ class ReferenceType : public TypeNoBounds
682707
lifetime->get_locus ())
683708
: tl::nullopt);
684709
}
710+
711+
Type::Kind get_type_kind () const override { return Type::Kind::Reference; }
685712
};
686713

687714
// A fixed-size sequence of elements of a specified type
@@ -758,6 +785,8 @@ class ArrayType : public TypeNoBounds
758785
size /* FIXME: This should be `reconstruct_expr()` */,
759786
locus);
760787
}
788+
789+
Type::Kind get_type_kind () const override { return Type::Kind::Array; }
761790
};
762791

763792
/* A dynamically-sized type representing a "view" into a sequence of elements of
@@ -818,6 +847,8 @@ class SliceType : public TypeNoBounds
818847
{
819848
return new SliceType (elem_type->reconstruct (), locus);
820849
}
850+
851+
Type::Kind get_type_kind () const override { return Type::Kind::Slice; }
821852
};
822853

823854
/* Type used in generic arguments to explicitly request type inference (wildcard
@@ -851,6 +882,8 @@ class InferredType : public TypeNoBounds
851882
location_t get_locus () const override final { return locus; }
852883

853884
void accept_vis (ASTVisitor &vis) override;
885+
886+
Type::Kind get_type_kind () const override { return Type::Kind::Inferred; }
854887
};
855888

856889
class QualifiedPathInType; // definition moved to "rust-path.h"
@@ -1086,6 +1119,11 @@ class BareFunctionType : public TypeNoBounds
10861119
{
10871120
return new BareFunctionType (*this);
10881121
}
1122+
1123+
Type::Kind get_type_kind () const override
1124+
{
1125+
return Type::Kind::BareFunction;
1126+
}
10891127
};
10901128

10911129
// Forward decl - defined in rust-macro.h

gcc/rust/resolve/rust-default-resolver.cc

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,13 @@
1717
// <http://www.gnu.org/licenses/>.
1818

1919
#include "rust-default-resolver.h"
20+
#include "optional.h"
2021
#include "rust-ast-full.h"
2122
#include "rust-ast-visitor.h"
23+
#include "rust-ast.h"
24+
#include "rust-attribute-values.h"
2225
#include "rust-item.h"
26+
#include "rust-path.h"
2327

2428
namespace Rust {
2529
namespace Resolver2_0 {
@@ -149,6 +153,16 @@ DefaultResolver::visit (AST::Trait &trait)
149153
trait.get_identifier () /* FIXME: Is that valid?*/);
150154
}
151155

156+
static bool
157+
is_lang_impl (std::vector<AST::Attribute> &outer_attrs)
158+
{
159+
for (auto &attr : outer_attrs)
160+
if (attr.get_path ().as_string () == Values::Attributes::LANG)
161+
return true;
162+
163+
return false;
164+
}
165+
152166
void
153167
DefaultResolver::visit (AST::InherentImpl &impl)
154168
{
@@ -177,6 +191,17 @@ DefaultResolver::visit (AST::InherentImpl &impl)
177191
};
178192

179193
ctx.scoped (Rib::Kind::Generics, impl.get_node_id (), inner_fn_3);
194+
195+
if (is_lang_impl (impl.get_outer_attrs ()))
196+
{
197+
if (impl.get_type ().get_type_kind () == AST::Type::Kind::TypePath)
198+
{
199+
auto type = static_cast<AST::TypePath &> (impl.get_type ());
200+
auto type_name = type.as_string ();
201+
202+
ctx.types.insert_lang_prelude (type_name, impl.get_node_id ());
203+
}
204+
}
180205
}
181206

182207
void

gcc/rust/resolve/rust-forever-stack.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,14 @@ template <Namespace N> class ForeverStack
649649
tl::expected<NodeId, DuplicateNameError> insert_at_root (Identifier name,
650650
NodeId id);
651651

652+
/**
653+
* Insert an item within the lang prelude
654+
*
655+
* @param name The name of the definition
656+
* @param id Its NodeId
657+
*/
658+
void insert_lang_prelude (Identifier name, NodeId id);
659+
652660
/* Access the innermost `Rib` in this map */
653661
Rib &peek ();
654662
const Rib &peek () const;

gcc/rust/resolve/rust-forever-stack.hxx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,14 @@ ForeverStack<Namespace::Types>::insert_variant (Identifier name, NodeId node)
199199
Rib::Definition::NonShadowable (node, true));
200200
}
201201

202+
template <Namespace N>
203+
inline void
204+
ForeverStack<N>::insert_lang_prelude (Identifier name, NodeId id)
205+
{
206+
insert_inner (lang_prelude.rib, name.as_string (),
207+
Rib::Definition::NonShadowable (id, false));
208+
}
209+
202210
template <Namespace N>
203211
Rib &
204212
ForeverStack<N>::peek ()

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

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,16 @@ Late::visit_function_params (AST::Function &function)
238238
void
239239
Late::visit (AST::StructPatternFieldIdent &field)
240240
{
241+
// We need to check if the Identifier resolves to a variant or empty struct
242+
auto path = AST::SimplePath (field.get_identifier ());
243+
244+
if (auto resolved = ctx.resolve_path (path, Namespace::Types))
245+
{
246+
ctx.map_usage (Usage (field.get_node_id ()),
247+
Definition (resolved->get_node_id ()));
248+
return;
249+
}
250+
241251
visit_identifier_as_pattern (ctx, field.get_identifier (), field.get_locus (),
242252
field.get_node_id (), field.is_ref (),
243253
field.is_mut ());
@@ -324,6 +334,7 @@ Late::visit (AST::IdentifierExpr &expr)
324334
// TODO: same thing as visit(PathInExpression) here?
325335

326336
tl::optional<Rib::Definition> resolved = tl::nullopt;
337+
327338
if (auto value = ctx.values.get (expr.get_ident ()))
328339
{
329340
resolved = value;
@@ -613,13 +624,26 @@ Late::visit (AST::StructExprStructFields &s)
613624
{
614625
visit_outer_attrs (s);
615626
visit_inner_attrs (s);
616-
DefaultResolver::visit (s.get_struct_name ());
627+
628+
auto &path = s.get_struct_name ();
629+
630+
DefaultResolver::visit (path);
617631
if (s.has_struct_base ())
618632
visit (s.get_struct_base ());
619633
for (auto &field : s.get_fields ())
620634
visit (field);
621635

622-
resolve_type_path_like (ctx, block_big_self, s.get_struct_name ());
636+
auto resolved = ctx.resolve_path (path, Namespace::Types);
637+
638+
if (!resolved)
639+
{
640+
rust_error_at (path.get_locus (), ErrorCode::E0433,
641+
"could not resolve path %qs", path.as_string ().c_str ());
642+
return;
643+
}
644+
645+
ctx.map_usage (Usage (path.get_node_id ()),
646+
Definition (resolved->get_node_id ()));
623647
}
624648

625649
// needed because Late::visit (AST::GenericArg &) is non-virtual

gcc/rust/resolve/rust-name-resolution-context.h

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -592,27 +592,25 @@ class NameResolutionContext
592592
// If it fails, switch to std prelude resolution if it exists
593593
if (prelude && !resolved)
594594
{
595-
std::vector<Error> ignore_errors = {};
596-
597595
// TODO: Factor this with the above
598596
switch (ns)
599597
{
600598
case Namespace::Values:
601599
return values.resolve_path (segments, mode,
602600
insert_segment_resolution,
603-
ignore_errors, *prelude);
601+
collect_errors, *prelude);
604602
case Namespace::Types:
605603
return types.resolve_path (segments, mode,
606-
insert_segment_resolution, ignore_errors,
607-
*prelude);
604+
insert_segment_resolution,
605+
collect_errors, *prelude);
608606
case Namespace::Macros:
609607
return macros.resolve_path (segments, mode,
610608
insert_segment_resolution,
611-
ignore_errors, *prelude);
609+
collect_errors, *prelude);
612610
case Namespace::Labels:
613611
return labels.resolve_path (segments, mode,
614612
insert_segment_resolution,
615-
ignore_errors, *prelude);
613+
collect_errors, *prelude);
616614
default:
617615
rust_unreachable ();
618616
}

0 commit comments

Comments
 (0)