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