Line data Source code
1 : // Copyright (C) 2020-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_HIR_PATH_H
20 : #define RUST_HIR_PATH_H
21 :
22 : #include "rust-hir-map.h"
23 : #include "rust-hir-simple-path.h"
24 : #include "rust-hir-type-no-bounds.h"
25 : #include "rust-hir-pattern-abstract.h"
26 : #include "rust-hir-expr-abstract.h"
27 :
28 : namespace Rust {
29 : namespace HIR {
30 :
31 : // The "identifier" (not generic args) aspect of each path expression segment
32 183309 : class PathIdentSegment
33 : {
34 : std::string segment_name;
35 :
36 : // TODO: should this have location info stored?
37 :
38 : // only allow identifiers, "super", "self", "Self", "crate", or "$crate"
39 : public:
40 160139 : PathIdentSegment (std::string segment_name)
41 150314 : : segment_name (std::move (segment_name))
42 : {}
43 :
44 412001 : PathIdentSegment (const PathIdentSegment &other)
45 758468 : : segment_name (other.segment_name)
46 : {}
47 :
48 0 : PathIdentSegment &operator= (PathIdentSegment const &other)
49 : {
50 0 : segment_name = other.segment_name;
51 0 : return *this;
52 : }
53 :
54 : // Creates an error PathIdentSegment.
55 9825 : static PathIdentSegment create_error () { return PathIdentSegment (""); }
56 :
57 : // Returns whether PathIdentSegment is in an error state.
58 15973 : bool is_error () const { return segment_name.empty (); }
59 :
60 240835 : std::string to_string () const { return segment_name; }
61 : };
62 :
63 : // A binding of an identifier to a type used in generic arguments in paths
64 : class GenericArgsBinding
65 : {
66 : public:
67 : enum class Kind
68 : {
69 : Equality,
70 : Constraint
71 : };
72 :
73 : private:
74 : Identifier identifier;
75 : std::unique_ptr<Type> type;
76 :
77 : location_t locus;
78 : Kind kind;
79 :
80 : public:
81 : // Returns whether binding is in an error state.
82 : bool is_error () const
83 : {
84 : return type == nullptr;
85 : // and also identifier is empty, but cheaper computation
86 : }
87 :
88 : // Creates an error state generic args binding.
89 : static GenericArgsBinding create_error ()
90 : {
91 : return GenericArgsBinding ({""}, nullptr);
92 : }
93 :
94 : // Pointer type for type in constructor to enable polymorphism
95 : GenericArgsBinding (Identifier ident, std::unique_ptr<Type> type_ptr,
96 : location_t locus = UNDEF_LOCATION,
97 : Kind kind = Kind::Equality);
98 :
99 : // Copy constructor has to deep copy the type as it is a unique pointer
100 : GenericArgsBinding (GenericArgsBinding const &other);
101 :
102 : // default destructor
103 438 : ~GenericArgsBinding () = default;
104 :
105 : // Overload assignment operator to deep copy the pointed-to type
106 : GenericArgsBinding &operator= (GenericArgsBinding const &other);
107 :
108 : // move constructors
109 93 : GenericArgsBinding (GenericArgsBinding &&other) = default;
110 : GenericArgsBinding &operator= (GenericArgsBinding &&other) = default;
111 :
112 : std::string to_string () const;
113 :
114 : Identifier &get_identifier () { return identifier; }
115 : const Identifier &get_identifier () const { return identifier; }
116 :
117 204 : Type &get_type ()
118 : {
119 204 : rust_assert (type);
120 204 : return *type;
121 : }
122 : const Type &get_type () const
123 : {
124 : rust_assert (type);
125 : return *type;
126 : }
127 :
128 3 : location_t get_locus () const { return locus; }
129 119 : Kind get_kind () const { return kind; }
130 : };
131 :
132 201 : class ConstGenericArg
133 : {
134 : // FIXME: Do we need to disambiguate or no? We should be able to disambiguate
135 : // at name-resolution, hence no need for ambiguities here
136 :
137 : public:
138 : ConstGenericArg (std::unique_ptr<Expr> expression, location_t locus);
139 :
140 : ConstGenericArg (const ConstGenericArg &other);
141 :
142 : ConstGenericArg operator= (const ConstGenericArg &other);
143 :
144 153 : std::unique_ptr<Expr> &get_expression () { return expression; }
145 :
146 118 : location_t get_locus () const { return locus; }
147 :
148 : private:
149 : std::unique_ptr<Expr> expression;
150 : location_t locus;
151 : };
152 :
153 : class GenericArgs
154 : {
155 : std::vector<Lifetime> lifetime_args;
156 : std::vector<std::unique_ptr<Type> > type_args;
157 : std::vector<GenericArgsBinding> binding_args;
158 : std::vector<ConstGenericArg> const_args;
159 : location_t locus;
160 :
161 : public:
162 : // Returns true if there are any generic arguments
163 121453 : bool has_generic_args () const
164 : {
165 237707 : return !(lifetime_args.empty () && type_args.empty ()
166 116446 : && binding_args.empty () && const_args.empty ());
167 : }
168 :
169 : GenericArgs (std::vector<Lifetime> lifetime_args,
170 : std::vector<std::unique_ptr<Type> > type_args,
171 : std::vector<GenericArgsBinding> binding_args,
172 : std::vector<ConstGenericArg> const_args, location_t locus);
173 :
174 : // copy constructor with vector clone
175 : GenericArgs (GenericArgs const &other);
176 :
177 250044 : ~GenericArgs () = default;
178 :
179 : // overloaded assignment operator to vector clone
180 : GenericArgs &operator= (GenericArgs const &other);
181 :
182 : // move constructors
183 113255 : GenericArgs (GenericArgs &&other) = default;
184 7306 : GenericArgs &operator= (GenericArgs &&other) = default;
185 :
186 : // Creates an empty GenericArgs (no arguments)
187 75988 : static GenericArgs create_empty (location_t locus = UNDEF_LOCATION)
188 : {
189 75988 : return GenericArgs ({}, {}, {}, {}, locus);
190 : }
191 :
192 : bool is_empty () const;
193 :
194 : std::string to_string () const;
195 :
196 9859 : std::vector<Lifetime> &get_lifetime_args () { return lifetime_args; }
197 : const std::vector<Lifetime> &get_lifetime_args () const
198 : {
199 10954 : return lifetime_args;
200 : }
201 :
202 14280 : std::vector<std::unique_ptr<Type> > &get_type_args () { return type_args; }
203 :
204 10288 : std::vector<GenericArgsBinding> &get_binding_args () { return binding_args; }
205 :
206 20823 : std::vector<ConstGenericArg> &get_const_args () { return const_args; }
207 :
208 19669 : location_t get_locus () const { return locus; }
209 : };
210 :
211 : /* A segment of a path in expression, including an identifier aspect and maybe
212 : * generic args */
213 158951 : class PathExprSegment
214 : {
215 : private:
216 : Analysis::NodeMapping mappings;
217 : PathIdentSegment segment_name;
218 : GenericArgs generic_args;
219 : location_t locus;
220 :
221 : public:
222 : PathExprSegment (Analysis::NodeMapping mappings,
223 : PathIdentSegment segment_name, location_t locus,
224 : GenericArgs generic_args);
225 :
226 : PathExprSegment (PathExprSegment const &other);
227 :
228 : PathExprSegment &operator= (PathExprSegment const &other);
229 :
230 : // move constructors
231 83308 : PathExprSegment (PathExprSegment &&other) = default;
232 : PathExprSegment &operator= (PathExprSegment &&other) = default;
233 :
234 : std::string to_string () const;
235 :
236 41949 : location_t get_locus () const { return locus; }
237 :
238 50850 : PathIdentSegment &get_segment () { return segment_name; }
239 46855 : const PathIdentSegment &get_segment () const { return segment_name; }
240 :
241 : GenericArgs &get_generic_args () { return generic_args; }
242 :
243 166062 : const Analysis::NodeMapping &get_mappings () const { return mappings; }
244 :
245 117829 : bool has_generic_args () const { return generic_args.has_generic_args (); }
246 : };
247 :
248 : // HIR node representing a pattern that involves a "path" - abstract base class
249 : class PathPattern : public Pattern
250 : {
251 : public:
252 : enum class Kind
253 : {
254 : Segmented,
255 : LangItem
256 : };
257 :
258 : private:
259 : std::vector<PathExprSegment> segments;
260 : tl::optional<LangItem::Kind> lang_item;
261 : Kind kind;
262 :
263 : protected:
264 54868 : PathPattern (std::vector<PathExprSegment> segments)
265 54868 : : segments (std::move (segments)), lang_item (tl::nullopt),
266 54868 : kind (Kind::Segmented)
267 54868 : {}
268 :
269 183 : PathPattern (LangItem::Kind lang_item)
270 183 : : segments ({}), lang_item (lang_item), kind (Kind::LangItem)
271 183 : {}
272 : bool is_refutable (const TyTy::BaseType &scrutinee) const override;
273 0 : bool is_refutable () const override
274 : {
275 : // Needs to be called with the other overload
276 0 : rust_unreachable ();
277 : }
278 :
279 : // Returns whether path has segments.
280 5 : bool has_segments () const
281 : {
282 5 : rust_assert (kind == Kind::Segmented);
283 5 : return !segments.empty ();
284 : }
285 :
286 : /* Converts path segments to their equivalent SimplePath segments if possible,
287 : * and creates a SimplePath from them. */
288 : AST::SimplePath
289 : convert_to_simple_path (bool with_opening_scope_resolution) const;
290 :
291 : public:
292 : /* Returns whether the path is a single segment (excluding qualified path
293 : * initial as segment). */
294 0 : bool is_single_segment () const
295 : {
296 0 : rust_assert (kind == Kind::Segmented);
297 0 : return segments.size () == 1;
298 : }
299 :
300 : std::string to_string () const override;
301 :
302 : void iterate_path_segments (std::function<bool (PathExprSegment &)> cb);
303 :
304 117941 : size_t get_num_segments () const
305 : {
306 117941 : rust_assert (kind == Kind::Segmented);
307 117941 : return segments.size ();
308 : }
309 :
310 119887 : std::vector<PathExprSegment> &get_segments ()
311 : {
312 119887 : rust_assert (kind == Kind::Segmented);
313 119887 : return segments;
314 : }
315 :
316 : const std::vector<PathExprSegment> &get_segments () const
317 : {
318 : rust_assert (kind == Kind::Segmented);
319 : return segments;
320 : }
321 :
322 : PathExprSegment &get_root_seg ()
323 : {
324 : rust_assert (kind == Kind::Segmented);
325 : return segments.at (0);
326 : }
327 :
328 46864 : const PathExprSegment &get_final_segment () const
329 : {
330 46864 : rust_assert (kind == Kind::Segmented);
331 46864 : return segments.back ();
332 : }
333 :
334 529 : LangItem::Kind get_lang_item () const
335 : {
336 529 : rust_assert (kind == Kind::LangItem);
337 :
338 529 : return *lang_item;
339 : }
340 :
341 784 : PatternType get_pattern_type () const override final
342 : {
343 784 : return PatternType::PATH;
344 : }
345 :
346 195182 : bool is_lang_item () const { return kind == Kind::LangItem; }
347 :
348 0 : Kind get_path_kind () const { return kind; }
349 : };
350 :
351 : /* HIR node representing a path-in-expression pattern (path that allows generic
352 : * arguments) */
353 : class PathInExpression : public PathPattern, public PathExpr
354 : {
355 : bool has_opening_scope_resolution;
356 : location_t locus;
357 :
358 : public:
359 : std::string to_string () const override;
360 :
361 : // Constructor
362 : PathInExpression (Analysis::NodeMapping mappings,
363 : std::vector<PathExprSegment> path_segments,
364 : location_t locus = UNDEF_LOCATION,
365 : bool has_opening_scope_resolution = false,
366 : std::vector<AST::Attribute> outer_attrs
367 : = std::vector<AST::Attribute> ());
368 :
369 : // lang-item Constructor
370 : PathInExpression (Analysis::NodeMapping mappings, LangItem::Kind kind,
371 : location_t locus = UNDEF_LOCATION,
372 : bool has_opening_scope_resolution = false,
373 : std::vector<AST::Attribute> outer_attrs
374 : = std::vector<AST::Attribute> ());
375 :
376 : // Creates an error state path in expression.
377 : static PathInExpression create_error ()
378 : {
379 : return PathInExpression (Analysis::NodeMapping::get_error (),
380 : std::vector<PathExprSegment> ());
381 : }
382 :
383 : // Returns whether path in expression is in an error state.
384 : bool is_error () const { return !has_segments (); }
385 :
386 : /* Converts PathInExpression to SimplePath if possible (i.e. no generic
387 : * arguments). Otherwise returns an empty SimplePath. */
388 5 : AST::SimplePath as_simple_path () const
389 : {
390 : /* delegate to parent class as can't access segments. however,
391 : * QualifiedPathInExpression conversion to simple path wouldn't make sense,
392 : * so the method in the parent class should be protected, not public. Have
393 : * to pass in opening scope resolution as parent class has no access to it.
394 : */
395 5 : return convert_to_simple_path (has_opening_scope_resolution);
396 : }
397 :
398 242066 : location_t get_locus () const override final { return locus; }
399 :
400 : void accept_vis (HIRFullVisitor &vis) override;
401 : void accept_vis (HIRExpressionVisitor &vis) override;
402 : void accept_vis (HIRPatternVisitor &vis) override;
403 :
404 0 : bool opening_scope_resolution () { return has_opening_scope_resolution; }
405 :
406 : bool is_self () const;
407 :
408 191224 : const Analysis::NodeMapping &get_mappings () const override final
409 : {
410 191224 : return mappings;
411 : }
412 :
413 : protected:
414 : /* Use covariance to implement clone function as returning this object rather
415 : * than base */
416 2006 : PathInExpression *clone_pattern_impl () const override
417 : {
418 2006 : return new PathInExpression (*this);
419 : }
420 :
421 : /* Use covariance to implement clone function as returning this object rather
422 : * than base */
423 832 : PathInExpression *clone_expr_without_block_impl () const override
424 : {
425 832 : return new PathInExpression (*this);
426 : }
427 : };
428 :
429 : /* Base class for segments used in type paths - not abstract (represents an
430 : * ident-only segment) */
431 : class TypePathSegment
432 : {
433 : public:
434 : enum SegmentType
435 : {
436 : REG,
437 : GENERIC,
438 : FUNCTION
439 : };
440 :
441 : private:
442 : Analysis::NodeMapping mappings;
443 : tl::optional<PathIdentSegment> ident_segment;
444 : tl::optional<LangItem::Kind> lang_item;
445 : location_t locus;
446 :
447 : protected:
448 : bool has_separating_scope_resolution;
449 : SegmentType type;
450 :
451 : public:
452 : // Clone function implementation - not pure virtual as overrided by subclasses
453 16477 : virtual TypePathSegment *clone_type_path_segment_impl () const
454 : {
455 16477 : return new TypePathSegment (*this);
456 : }
457 :
458 : public:
459 27998 : virtual ~TypePathSegment () {}
460 :
461 60831 : virtual SegmentType get_type () const { return SegmentType::REG; }
462 :
463 : // Unique pointer custom clone function
464 17601 : std::unique_ptr<TypePathSegment> clone_type_path_segment () const
465 : {
466 17601 : return std::unique_ptr<TypePathSegment> (clone_type_path_segment_impl ());
467 : }
468 :
469 : TypePathSegment (Analysis::NodeMapping mappings,
470 : PathIdentSegment ident_segment,
471 : bool has_separating_scope_resolution, location_t locus);
472 :
473 : TypePathSegment (Analysis::NodeMapping mappings, LangItem::Kind lang_item,
474 : location_t locus);
475 :
476 : TypePathSegment (Analysis::NodeMapping mappings, std::string segment_name,
477 : bool has_separating_scope_resolution, location_t locus);
478 :
479 110621 : virtual std::string to_string () const
480 : {
481 110621 : if (ident_segment)
482 110621 : return ident_segment->to_string ();
483 :
484 0 : return LangItem::PrettyString (*lang_item);
485 : }
486 :
487 : /* Returns whether the type path segment is in an error state. May be virtual
488 : * in future. */
489 3 : bool is_error () const
490 : {
491 3 : rust_assert (ident_segment);
492 3 : return ident_segment->is_error ();
493 : }
494 :
495 : /* Returns whether segment is identifier only (as opposed to generic args or
496 : * function). Overriden in derived classes with other segments. */
497 52002 : virtual bool is_ident_only () const { return true; }
498 :
499 96 : location_t get_locus () const { return locus; }
500 :
501 : // not pure virtual as class not abstract
502 : virtual void accept_vis (HIRFullVisitor &vis);
503 :
504 55239 : const Analysis::NodeMapping &get_mappings () const { return mappings; }
505 :
506 1362 : const PathIdentSegment &get_ident_segment () const
507 : {
508 1362 : rust_assert (ident_segment);
509 1362 : return *ident_segment;
510 : }
511 :
512 50 : const LangItem::Kind &get_lang_item () const
513 : {
514 50 : rust_assert (lang_item);
515 50 : return *lang_item;
516 : }
517 :
518 54891 : bool is_generic_segment () const
519 : {
520 54891 : return get_type () == SegmentType::GENERIC;
521 : }
522 :
523 55206 : bool is_lang_item () const { return lang_item.has_value (); }
524 : };
525 :
526 : // Segment used in type path with generic args
527 : class TypePathSegmentGeneric : public TypePathSegment
528 : {
529 : GenericArgs generic_args;
530 :
531 : public:
532 3624 : bool has_generic_args () const { return generic_args.has_generic_args (); }
533 :
534 2092 : bool is_ident_only () const override { return false; }
535 :
536 : // Constructor with PathIdentSegment and GenericArgs
537 : TypePathSegmentGeneric (Analysis::NodeMapping mappings,
538 : PathIdentSegment ident_segment,
539 : bool has_separating_scope_resolution,
540 : GenericArgs generic_args, location_t locus);
541 :
542 : TypePathSegmentGeneric (Analysis::NodeMapping mappings,
543 : LangItem::Kind lang_item, GenericArgs generic_args,
544 : location_t locus);
545 :
546 : // Constructor from segment name and all args
547 : TypePathSegmentGeneric (Analysis::NodeMapping mappings,
548 : std::string segment_name,
549 : bool has_separating_scope_resolution,
550 : std::vector<Lifetime> lifetime_args,
551 : std::vector<std::unique_ptr<Type> > type_args,
552 : std::vector<GenericArgsBinding> binding_args,
553 : std::vector<ConstGenericArg> const_args,
554 : location_t locus);
555 :
556 : std::string to_string () const override;
557 :
558 : void accept_vis (HIRFullVisitor &vis) override;
559 :
560 2112 : GenericArgs &get_generic_args () { return generic_args; }
561 :
562 3174 : virtual SegmentType get_type () const override final
563 : {
564 3174 : return SegmentType::GENERIC;
565 : }
566 :
567 : // Use covariance to override base class method
568 1124 : TypePathSegmentGeneric *clone_type_path_segment_impl () const override
569 : {
570 1124 : return new TypePathSegmentGeneric (*this);
571 : }
572 : };
573 :
574 : // A function as represented in a type path
575 : class TypePathFunction
576 : {
577 : std::vector<std::unique_ptr<Type> > inputs;
578 : std::unique_ptr<Type> return_type;
579 :
580 : public:
581 : // Returns whether the return type of the function has been specified.
582 88 : bool has_return_type () const { return return_type != nullptr; }
583 :
584 : // Returns whether the function has inputs.
585 28 : bool has_inputs () const { return !inputs.empty (); }
586 :
587 : // Constructor
588 : TypePathFunction (std::vector<std::unique_ptr<Type> > inputs,
589 : std::unique_ptr<Type> type);
590 :
591 : // Copy constructor with clone
592 : TypePathFunction (TypePathFunction const &other);
593 :
594 31 : ~TypePathFunction () = default;
595 :
596 : // Overloaded assignment operator to clone type
597 : TypePathFunction &operator= (TypePathFunction const &other);
598 :
599 : // move constructors
600 62 : TypePathFunction (TypePathFunction &&other) = default;
601 : TypePathFunction &operator= (TypePathFunction &&other) = default;
602 :
603 : std::string to_string () const;
604 :
605 : const std::vector<std::unique_ptr<Type> > &get_params () const
606 : {
607 : return inputs;
608 : };
609 56 : std::vector<std::unique_ptr<Type> > &get_params () { return inputs; };
610 :
611 29 : const Type &get_return_type () const { return *return_type; };
612 56 : Type &get_return_type () { return *return_type; };
613 : };
614 :
615 : // Segment used in type path with a function argument
616 : class TypePathSegmentFunction : public TypePathSegment
617 : {
618 : TypePathFunction function_path;
619 :
620 : public:
621 : // Constructor with PathIdentSegment and TypePathFn
622 : TypePathSegmentFunction (Analysis::NodeMapping mappings,
623 : PathIdentSegment ident_segment,
624 : bool has_separating_scope_resolution,
625 : TypePathFunction function_path, location_t locus);
626 :
627 : // Constructor with segment name and TypePathFn
628 : TypePathSegmentFunction (Analysis::NodeMapping mappings,
629 : std::string segment_name,
630 : bool has_separating_scope_resolution,
631 : TypePathFunction function_path, location_t locus);
632 :
633 : std::string to_string () const override;
634 :
635 0 : bool is_ident_only () const override { return false; }
636 :
637 : void accept_vis (HIRFullVisitor &vis) override;
638 :
639 29 : SegmentType get_type () const override final { return SegmentType::FUNCTION; }
640 :
641 57 : TypePathFunction &get_function_path () { return function_path; }
642 :
643 : // Use covariance to override base class method
644 31 : TypePathSegmentFunction *clone_type_path_segment_impl () const override
645 : {
646 31 : return new TypePathSegmentFunction (*this);
647 : }
648 : };
649 :
650 : // Path used inside types
651 3620 : class TypePath : public TypeNoBounds
652 : {
653 : public:
654 : bool has_opening_scope_resolution;
655 : std::vector<std::unique_ptr<TypePathSegment> > segments;
656 :
657 : protected:
658 : /* Use covariance to implement clone function as returning this object rather
659 : * than base */
660 15023 : TypePath *clone_type_impl () const override { return new TypePath (*this); }
661 :
662 : /* Use covariance to implement clone function as returning this object rather
663 : * than base */
664 0 : TypePath *clone_type_no_bounds_impl () const override
665 : {
666 0 : return new TypePath (*this);
667 : }
668 :
669 : public:
670 : /* Returns whether the TypePath has an opening scope resolution operator (i.e.
671 : * is global path or crate-relative path, not module-relative) */
672 0 : bool has_opening_scope_resolution_op () const
673 : {
674 0 : return has_opening_scope_resolution;
675 : }
676 :
677 : // Returns whether the TypePath is in an invalid state.
678 : bool is_error () const { return segments.empty (); }
679 :
680 : // Creates an error state TypePath.
681 : static TypePath create_error ()
682 : {
683 : return TypePath (Analysis::NodeMapping::get_error (),
684 : std::vector<std::unique_ptr<TypePathSegment> > (),
685 : UNDEF_LOCATION);
686 : }
687 :
688 : // Constructor
689 : TypePath (Analysis::NodeMapping mappings,
690 : std::vector<std::unique_ptr<TypePathSegment> > segments,
691 : location_t locus, bool has_opening_scope_resolution = false);
692 :
693 : // Copy constructor with vector clone
694 : TypePath (TypePath const &other);
695 :
696 : // Overloaded assignment operator with clone
697 : TypePath &operator= (TypePath const &other);
698 :
699 : // move constructors
700 3620 : TypePath (TypePath &&other) = default;
701 : TypePath &operator= (TypePath &&other) = default;
702 :
703 : std::string to_string () const override;
704 :
705 : /* Converts TypePath to SimplePath if possible (i.e. no generic or function
706 : * arguments). Otherwise returns an empty SimplePath. */
707 : AST::SimplePath as_simple_path () const;
708 :
709 : // Creates a trait bound with a clone of this type path as its only element.
710 : std::unique_ptr<TraitBound> to_trait_bound (bool in_parens) const override;
711 :
712 : void accept_vis (HIRFullVisitor &vis) override;
713 : void accept_vis (HIRTypeVisitor &vis) override;
714 :
715 161296 : size_t get_num_segments () const { return segments.size (); }
716 :
717 56322 : std::vector<std::unique_ptr<TypePathSegment> > &get_segments ()
718 : {
719 107678 : return segments;
720 : }
721 :
722 8898 : TypePathSegment &get_final_segment () { return *segments.back (); }
723 : };
724 :
725 : class QualifiedPathType
726 : {
727 : std::unique_ptr<Type> type;
728 : std::unique_ptr<TypePath> trait;
729 : location_t locus;
730 : Analysis::NodeMapping mappings;
731 :
732 : public:
733 : // Constructor
734 : QualifiedPathType (Analysis::NodeMapping mappings, std::unique_ptr<Type> type,
735 : std::unique_ptr<TypePath> trait, location_t locus);
736 :
737 : // Copy constructor uses custom deep copy for Type to preserve polymorphism
738 : QualifiedPathType (QualifiedPathType const &other);
739 :
740 : // default destructor
741 1113 : ~QualifiedPathType () = default;
742 :
743 : // overload assignment operator to use custom clone method
744 : QualifiedPathType &operator= (QualifiedPathType const &other);
745 :
746 : // move constructor
747 618 : QualifiedPathType (QualifiedPathType &&other) = default;
748 : QualifiedPathType &operator= (QualifiedPathType &&other) = default;
749 :
750 : // Returns whether the qualified path type has a rebind as clause.
751 1185 : bool has_as_clause () const { return trait != nullptr; }
752 :
753 : std::string to_string () const;
754 :
755 : location_t get_locus () const { return locus; }
756 :
757 0 : Analysis::NodeMapping get_mappings () const { return mappings; }
758 :
759 0 : bool has_type () { return type != nullptr; }
760 0 : bool has_trait () { return trait != nullptr; }
761 :
762 977 : Type &get_type ()
763 : {
764 977 : rust_assert (type);
765 977 : return *type;
766 : }
767 :
768 816 : TypePath &get_trait ()
769 : {
770 816 : rust_assert (trait);
771 816 : return *trait;
772 : }
773 :
774 : bool trait_has_generic_args () const;
775 :
776 : GenericArgs &get_trait_generic_args ();
777 : };
778 :
779 : /* HIR node representing a qualified path-in-expression pattern (path that
780 : * allows specifying trait functions) */
781 : class QualifiedPathInExpression : public PathPattern, public PathExpr
782 : {
783 : QualifiedPathType path_type;
784 : location_t locus;
785 :
786 : public:
787 : std::string to_string () const override;
788 :
789 : QualifiedPathInExpression (Analysis::NodeMapping mappings,
790 : QualifiedPathType qual_path_type,
791 : std::vector<PathExprSegment> path_segments,
792 : location_t locus = UNDEF_LOCATION,
793 : std::vector<AST::Attribute> outer_attrs
794 : = std::vector<AST::Attribute> ());
795 :
796 : // lang-item constructor
797 : QualifiedPathInExpression (Analysis::NodeMapping mappings,
798 : QualifiedPathType qual_path_type,
799 : LangItem::Kind lang_item,
800 : location_t locus = UNDEF_LOCATION,
801 : std::vector<AST::Attribute> outer_attrs
802 : = std::vector<AST::Attribute> ());
803 :
804 163 : location_t get_locus () const override final { return locus; }
805 :
806 : void accept_vis (HIRFullVisitor &vis) override;
807 : void accept_vis (HIRExpressionVisitor &vis) override;
808 : void accept_vis (HIRPatternVisitor &vis) override;
809 :
810 203 : QualifiedPathType &get_path_type () { return path_type; }
811 :
812 235 : location_t get_locus () { return locus; }
813 :
814 357 : const Analysis::NodeMapping &get_mappings () const override final
815 : {
816 357 : return mappings;
817 : }
818 :
819 : protected:
820 : /* Use covariance to implement clone function as returning this object rather
821 : * than base */
822 0 : QualifiedPathInExpression *clone_pattern_impl () const override
823 : {
824 0 : return new QualifiedPathInExpression (*this);
825 : }
826 :
827 : /* Use covariance to implement clone function as returning this object rather
828 : * than base */
829 0 : QualifiedPathInExpression *clone_expr_without_block_impl () const override
830 : {
831 0 : return new QualifiedPathInExpression (*this);
832 : }
833 : };
834 :
835 : /* Represents a qualified path in a type; used for disambiguating trait function
836 : * calls */
837 : class QualifiedPathInType : public TypeNoBounds
838 : {
839 : QualifiedPathType path_type;
840 : std::unique_ptr<TypePathSegment> associated_segment;
841 : std::vector<std::unique_ptr<TypePathSegment> > segments;
842 :
843 : protected:
844 : /* Use covariance to implement clone function as returning this object rather
845 : * than base */
846 31 : QualifiedPathInType *clone_type_impl () const override
847 : {
848 31 : return new QualifiedPathInType (*this);
849 : }
850 :
851 : /* Use covariance to implement clone function as returning this object rather
852 : * than base */
853 0 : QualifiedPathInType *clone_type_no_bounds_impl () const override
854 : {
855 0 : return new QualifiedPathInType (*this);
856 : }
857 :
858 : public:
859 : QualifiedPathInType (
860 : Analysis::NodeMapping mappings, QualifiedPathType qual_path_type,
861 : std::unique_ptr<TypePathSegment> associated_segment,
862 : std::vector<std::unique_ptr<TypePathSegment> > path_segments,
863 : location_t locus = UNDEF_LOCATION);
864 :
865 : // Copy constructor with vector clone
866 : QualifiedPathInType (QualifiedPathInType const &other);
867 :
868 : // Overloaded assignment operator with vector clone
869 : QualifiedPathInType &operator= (QualifiedPathInType const &other);
870 :
871 : // move constructors
872 : QualifiedPathInType (QualifiedPathInType &&other) = default;
873 : QualifiedPathInType &operator= (QualifiedPathInType &&other) = default;
874 :
875 : std::string to_string () const override;
876 :
877 : void accept_vis (HIRFullVisitor &vis) override;
878 : void accept_vis (HIRTypeVisitor &vis) override;
879 :
880 448 : QualifiedPathType &get_path_type () { return path_type; }
881 :
882 447 : TypePathSegment &get_associated_segment () { return *associated_segment; }
883 :
884 1 : std::vector<std::unique_ptr<TypePathSegment> > &get_segments ()
885 : {
886 447 : return segments;
887 : }
888 : };
889 :
890 : } // namespace HIR
891 : } // namespace Rust
892 :
893 : #endif
|