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 167599 : 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 146999 : PathIdentSegment (std::string segment_name)
41 137910 : : segment_name (std::move (segment_name))
42 : {}
43 :
44 382528 : PathIdentSegment (const PathIdentSegment &other)
45 705625 : : 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 9089 : static PathIdentSegment create_error () { return PathIdentSegment (""); }
56 :
57 : // Returns whether PathIdentSegment is in an error state.
58 14725 : bool is_error () const { return segment_name.empty (); }
59 :
60 652939 : 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 312 : ~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 162 : Type &get_type ()
108 : {
109 162 : rust_assert (type);
110 162 : 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 201 : 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 153 : std::unique_ptr<Expr> &get_expression () { return expression; }
134 :
135 118 : 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 116207 : bool has_generic_args () const
153 : {
154 227745 : return !(lifetime_args.empty () && type_args.empty ()
155 111674 : && 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 233979 : ~GenericArgs () = default;
167 :
168 : // overloaded assignment operator to vector clone
169 : GenericArgs &operator= (GenericArgs const &other);
170 :
171 : // move constructors
172 104485 : GenericArgs (GenericArgs &&other) = default;
173 6074 : GenericArgs &operator= (GenericArgs &&other) = default;
174 :
175 : // Creates an empty GenericArgs (no arguments)
176 69689 : static GenericArgs create_empty (location_t locus = UNDEF_LOCATION)
177 : {
178 69689 : return GenericArgs ({}, {}, {}, {}, locus);
179 : }
180 :
181 : bool is_empty () const;
182 :
183 : std::string to_string () const;
184 :
185 8412 : std::vector<Lifetime> &get_lifetime_args () { return lifetime_args; }
186 : const std::vector<Lifetime> &get_lifetime_args () const
187 : {
188 9413 : return lifetime_args;
189 : }
190 :
191 12508 : std::vector<std::unique_ptr<Type> > &get_type_args () { return type_args; }
192 :
193 8490 : std::vector<GenericArgsBinding> &get_binding_args () { return binding_args; }
194 :
195 17837 : std::vector<ConstGenericArg> &get_const_args () { return const_args; }
196 :
197 16652 : 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 151125 : 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 76548 : PathExprSegment (PathExprSegment &&other) = default;
221 : PathExprSegment &operator= (PathExprSegment &&other) = default;
222 :
223 : std::string to_string () const;
224 :
225 41516 : location_t get_locus () const { return locus; }
226 :
227 47693 : PathIdentSegment &get_segment () { return segment_name; }
228 43732 : const PathIdentSegment &get_segment () const { return segment_name; }
229 :
230 : GenericArgs &get_generic_args () { return generic_args; }
231 :
232 156675 : const Analysis::NodeMapping &get_mappings () const { return mappings; }
233 :
234 112975 : 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 51147 : PathPattern (std::vector<PathExprSegment> segments)
254 51147 : : segments (std::move (segments)), lang_item (tl::nullopt),
255 51147 : kind (Kind::Segmented)
256 51147 : {}
257 :
258 151 : PathPattern (LangItem::Kind lang_item)
259 151 : : segments ({}), lang_item (lang_item), kind (Kind::LangItem)
260 151 : {}
261 : bool is_refutable (const TyTy::BaseType &scrutinee) const override;
262 0 : bool is_refutable () const override
263 : {
264 : // Needs to be called with the other overload
265 0 : rust_unreachable ();
266 : }
267 :
268 : // Returns whether path has segments.
269 5 : bool has_segments () const
270 : {
271 5 : rust_assert (kind == Kind::Segmented);
272 5 : return !segments.empty ();
273 : }
274 :
275 : /* Converts path segments to their equivalent SimplePath segments if possible,
276 : * and creates a SimplePath from them. */
277 : AST::SimplePath
278 : convert_to_simple_path (bool with_opening_scope_resolution) const;
279 :
280 : public:
281 : /* Returns whether the path is a single segment (excluding qualified path
282 : * initial as segment). */
283 0 : bool is_single_segment () const
284 : {
285 0 : rust_assert (kind == Kind::Segmented);
286 0 : return segments.size () == 1;
287 : }
288 :
289 : std::string to_string () const override;
290 :
291 : void iterate_path_segments (std::function<bool (PathExprSegment &)> cb);
292 :
293 109363 : size_t get_num_segments () const
294 : {
295 109363 : rust_assert (kind == Kind::Segmented);
296 109363 : return segments.size ();
297 : }
298 :
299 111151 : std::vector<PathExprSegment> &get_segments ()
300 : {
301 111151 : rust_assert (kind == Kind::Segmented);
302 111151 : return segments;
303 : }
304 :
305 : const std::vector<PathExprSegment> &get_segments () const
306 : {
307 : rust_assert (kind == Kind::Segmented);
308 : return segments;
309 : }
310 :
311 : PathExprSegment &get_root_seg ()
312 : {
313 : rust_assert (kind == Kind::Segmented);
314 : return segments.at (0);
315 : }
316 :
317 43741 : const PathExprSegment &get_final_segment () const
318 : {
319 43741 : rust_assert (kind == Kind::Segmented);
320 43741 : return segments.back ();
321 : }
322 :
323 423 : LangItem::Kind get_lang_item () const
324 : {
325 423 : rust_assert (kind == Kind::LangItem);
326 :
327 423 : return *lang_item;
328 : }
329 :
330 768 : PatternType get_pattern_type () const override final
331 : {
332 768 : return PatternType::PATH;
333 : }
334 :
335 186873 : bool is_lang_item () const { return kind == Kind::LangItem; }
336 :
337 0 : Kind get_path_kind () const { return kind; }
338 : };
339 :
340 : /* HIR node representing a path-in-expression pattern (path that allows generic
341 : * arguments) */
342 : class PathInExpression : public PathPattern, public PathExpr
343 : {
344 : bool has_opening_scope_resolution;
345 : location_t locus;
346 :
347 : public:
348 : std::string to_string () const override;
349 :
350 : // Constructor
351 : PathInExpression (Analysis::NodeMapping mappings,
352 : std::vector<PathExprSegment> path_segments,
353 : location_t locus = UNDEF_LOCATION,
354 : bool has_opening_scope_resolution = false,
355 : std::vector<AST::Attribute> outer_attrs
356 : = std::vector<AST::Attribute> ());
357 :
358 : // lang-item Constructor
359 : PathInExpression (Analysis::NodeMapping mappings, LangItem::Kind kind,
360 : location_t locus = UNDEF_LOCATION,
361 : bool has_opening_scope_resolution = false,
362 : std::vector<AST::Attribute> outer_attrs
363 : = std::vector<AST::Attribute> ());
364 :
365 : // Creates an error state path in expression.
366 : static PathInExpression create_error ()
367 : {
368 : return PathInExpression (Analysis::NodeMapping::get_error (),
369 : std::vector<PathExprSegment> ());
370 : }
371 :
372 : // Returns whether path in expression is in an error state.
373 : bool is_error () const { return !has_segments (); }
374 :
375 : /* Converts PathInExpression to SimplePath if possible (i.e. no generic
376 : * arguments). Otherwise returns an empty SimplePath. */
377 5 : AST::SimplePath as_simple_path () const
378 : {
379 : /* delegate to parent class as can't access segments. however,
380 : * QualifiedPathInExpression conversion to simple path wouldn't make sense,
381 : * so the method in the parent class should be protected, not public. Have
382 : * to pass in opening scope resolution as parent class has no access to it.
383 : */
384 5 : return convert_to_simple_path (has_opening_scope_resolution);
385 : }
386 :
387 219458 : location_t get_locus () const override final { return locus; }
388 :
389 : void accept_vis (HIRFullVisitor &vis) override;
390 : void accept_vis (HIRExpressionVisitor &vis) override;
391 : void accept_vis (HIRPatternVisitor &vis) override;
392 :
393 0 : bool opening_scope_resolution () { return has_opening_scope_resolution; }
394 :
395 : bool is_self () const;
396 :
397 180883 : const Analysis::NodeMapping &get_mappings () const override final
398 : {
399 180883 : return mappings;
400 : }
401 :
402 : protected:
403 : /* Use covariance to implement clone function as returning this object rather
404 : * than base */
405 1981 : PathInExpression *clone_pattern_impl () const override
406 : {
407 1981 : return new PathInExpression (*this);
408 : }
409 :
410 : /* Use covariance to implement clone function as returning this object rather
411 : * than base */
412 826 : PathInExpression *clone_expr_without_block_impl () const override
413 : {
414 826 : return new PathInExpression (*this);
415 : }
416 : };
417 :
418 : /* Base class for segments used in type paths - not abstract (represents an
419 : * ident-only segment) */
420 : class TypePathSegment
421 : {
422 : public:
423 : enum SegmentType
424 : {
425 : REG,
426 : GENERIC,
427 : FUNCTION
428 : };
429 :
430 : private:
431 : Analysis::NodeMapping mappings;
432 : tl::optional<PathIdentSegment> ident_segment;
433 : tl::optional<LangItem::Kind> lang_item;
434 : location_t locus;
435 :
436 : protected:
437 : bool has_separating_scope_resolution;
438 : SegmentType type;
439 :
440 : public:
441 : // Clone function implementation - not pure virtual as overrided by subclasses
442 14119 : virtual TypePathSegment *clone_type_path_segment_impl () const
443 : {
444 14119 : return new TypePathSegment (*this);
445 : }
446 :
447 : public:
448 24096 : virtual ~TypePathSegment () {}
449 :
450 53388 : virtual SegmentType get_type () const { return SegmentType::REG; }
451 :
452 : // Unique pointer custom clone function
453 15151 : std::unique_ptr<TypePathSegment> clone_type_path_segment () const
454 : {
455 15151 : return std::unique_ptr<TypePathSegment> (clone_type_path_segment_impl ());
456 : }
457 :
458 : TypePathSegment (Analysis::NodeMapping mappings,
459 : PathIdentSegment ident_segment,
460 : bool has_separating_scope_resolution, location_t locus);
461 :
462 : TypePathSegment (Analysis::NodeMapping mappings, LangItem::Kind lang_item,
463 : location_t locus);
464 :
465 : TypePathSegment (Analysis::NodeMapping mappings, std::string segment_name,
466 : bool has_separating_scope_resolution, location_t locus);
467 :
468 98927 : virtual std::string to_string () const
469 : {
470 98927 : if (ident_segment)
471 98927 : return ident_segment->to_string ();
472 :
473 0 : return LangItem::PrettyString (*lang_item);
474 : }
475 :
476 : /* Returns whether the type path segment is in an error state. May be virtual
477 : * in future. */
478 3 : bool is_error () const
479 : {
480 3 : rust_assert (ident_segment);
481 3 : return ident_segment->is_error ();
482 : }
483 :
484 : /* Returns whether segment is identifier only (as opposed to generic args or
485 : * function). Overriden in derived classes with other segments. */
486 46435 : virtual bool is_ident_only () const { return true; }
487 :
488 90 : location_t get_locus () const { return locus; }
489 :
490 : // not pure virtual as class not abstract
491 : virtual void accept_vis (HIRFullVisitor &vis);
492 :
493 49407 : const Analysis::NodeMapping &get_mappings () const { return mappings; }
494 :
495 585 : const PathIdentSegment &get_ident_segment () const
496 : {
497 585 : rust_assert (ident_segment);
498 585 : return *ident_segment;
499 : }
500 :
501 49 : const LangItem::Kind &get_lang_item () const
502 : {
503 49 : rust_assert (lang_item);
504 49 : return *lang_item;
505 : }
506 :
507 49067 : bool is_generic_segment () const
508 : {
509 49067 : return get_type () == SegmentType::GENERIC;
510 : }
511 :
512 49376 : bool is_lang_item () const { return lang_item.has_value (); }
513 : };
514 :
515 : // Segment used in type path with generic args
516 : class TypePathSegmentGeneric : public TypePathSegment
517 : {
518 : GenericArgs generic_args;
519 :
520 : public:
521 3232 : bool has_generic_args () const { return generic_args.has_generic_args (); }
522 :
523 1921 : bool is_ident_only () const override { return false; }
524 :
525 : // Constructor with PathIdentSegment and GenericArgs
526 : TypePathSegmentGeneric (Analysis::NodeMapping mappings,
527 : PathIdentSegment ident_segment,
528 : bool has_separating_scope_resolution,
529 : GenericArgs generic_args, location_t locus);
530 :
531 : TypePathSegmentGeneric (Analysis::NodeMapping mappings,
532 : LangItem::Kind lang_item, GenericArgs generic_args,
533 : location_t locus);
534 :
535 : // Constructor from segment name and all args
536 : TypePathSegmentGeneric (Analysis::NodeMapping mappings,
537 : std::string segment_name,
538 : bool has_separating_scope_resolution,
539 : std::vector<Lifetime> lifetime_args,
540 : std::vector<std::unique_ptr<Type> > type_args,
541 : std::vector<GenericArgsBinding> binding_args,
542 : std::vector<ConstGenericArg> const_args,
543 : location_t locus);
544 :
545 : std::string to_string () const override;
546 :
547 : void accept_vis (HIRFullVisitor &vis) override;
548 :
549 1941 : GenericArgs &get_generic_args () { return generic_args; }
550 :
551 2828 : virtual SegmentType get_type () const override final
552 : {
553 2828 : return SegmentType::GENERIC;
554 : }
555 :
556 : // Use covariance to override base class method
557 1031 : TypePathSegmentGeneric *clone_type_path_segment_impl () const override
558 : {
559 1031 : return new TypePathSegmentGeneric (*this);
560 : }
561 : };
562 :
563 : // A function as represented in a type path
564 : class TypePathFunction
565 : {
566 : std::vector<std::unique_ptr<Type> > inputs;
567 : std::unique_ptr<Type> return_type;
568 :
569 : public:
570 : // Returns whether the return type of the function has been specified.
571 84 : bool has_return_type () const { return return_type != nullptr; }
572 :
573 : // Returns whether the function has inputs.
574 27 : bool has_inputs () const { return !inputs.empty (); }
575 :
576 : // Constructor
577 : TypePathFunction (std::vector<std::unique_ptr<Type> > inputs,
578 : std::unique_ptr<Type> type);
579 :
580 : // Copy constructor with clone
581 : TypePathFunction (TypePathFunction const &other);
582 :
583 30 : ~TypePathFunction () = default;
584 :
585 : // Overloaded assignment operator to clone type
586 : TypePathFunction &operator= (TypePathFunction const &other);
587 :
588 : // move constructors
589 60 : TypePathFunction (TypePathFunction &&other) = default;
590 : TypePathFunction &operator= (TypePathFunction &&other) = default;
591 :
592 : std::string to_string () const;
593 :
594 : const std::vector<std::unique_ptr<Type> > &get_params () const
595 : {
596 : return inputs;
597 : };
598 54 : std::vector<std::unique_ptr<Type> > &get_params () { return inputs; };
599 :
600 28 : const Type &get_return_type () const { return *return_type; };
601 81 : Type &get_return_type () { return *return_type; };
602 : };
603 :
604 : // Segment used in type path with a function argument
605 : class TypePathSegmentFunction : public TypePathSegment
606 : {
607 : TypePathFunction function_path;
608 :
609 : public:
610 : // Constructor with PathIdentSegment and TypePathFn
611 : TypePathSegmentFunction (Analysis::NodeMapping mappings,
612 : PathIdentSegment ident_segment,
613 : bool has_separating_scope_resolution,
614 : TypePathFunction function_path, location_t locus);
615 :
616 : // Constructor with segment name and TypePathFn
617 : TypePathSegmentFunction (Analysis::NodeMapping mappings,
618 : std::string segment_name,
619 : bool has_separating_scope_resolution,
620 : TypePathFunction function_path, location_t locus);
621 :
622 : std::string to_string () const override;
623 :
624 0 : bool is_ident_only () const override { return false; }
625 :
626 : void accept_vis (HIRFullVisitor &vis) override;
627 :
628 27 : SegmentType get_type () const override final { return SegmentType::FUNCTION; }
629 :
630 54 : TypePathFunction &get_function_path () { return function_path; }
631 :
632 : // Use covariance to override base class method
633 30 : TypePathSegmentFunction *clone_type_path_segment_impl () const override
634 : {
635 30 : return new TypePathSegmentFunction (*this);
636 : }
637 : };
638 :
639 : // Path used inside types
640 3192 : class TypePath : public TypeNoBounds
641 : {
642 : public:
643 : bool has_opening_scope_resolution;
644 : std::vector<std::unique_ptr<TypePathSegment> > segments;
645 :
646 : protected:
647 : /* Use covariance to implement clone function as returning this object rather
648 : * than base */
649 13023 : TypePath *clone_type_impl () const override { return new TypePath (*this); }
650 :
651 : /* Use covariance to implement clone function as returning this object rather
652 : * than base */
653 0 : TypePath *clone_type_no_bounds_impl () const override
654 : {
655 0 : return new TypePath (*this);
656 : }
657 :
658 : public:
659 : /* Returns whether the TypePath has an opening scope resolution operator (i.e.
660 : * is global path or crate-relative path, not module-relative) */
661 0 : bool has_opening_scope_resolution_op () const
662 : {
663 0 : return has_opening_scope_resolution;
664 : }
665 :
666 : // Returns whether the TypePath is in an invalid state.
667 : bool is_error () const { return segments.empty (); }
668 :
669 : // Creates an error state TypePath.
670 : static TypePath create_error ()
671 : {
672 : return TypePath (Analysis::NodeMapping::get_error (),
673 : std::vector<std::unique_ptr<TypePathSegment> > (),
674 : UNDEF_LOCATION);
675 : }
676 :
677 : // Constructor
678 : TypePath (Analysis::NodeMapping mappings,
679 : std::vector<std::unique_ptr<TypePathSegment> > segments,
680 : location_t locus, bool has_opening_scope_resolution = false);
681 :
682 : // Copy constructor with vector clone
683 : TypePath (TypePath const &other);
684 :
685 : // Overloaded assignment operator with clone
686 : TypePath &operator= (TypePath const &other);
687 :
688 : // move constructors
689 3192 : TypePath (TypePath &&other) = default;
690 : TypePath &operator= (TypePath &&other) = default;
691 :
692 : std::string to_string () const override;
693 :
694 : /* Converts TypePath to SimplePath if possible (i.e. no generic or function
695 : * arguments). Otherwise returns an empty SimplePath. */
696 : AST::SimplePath as_simple_path () const;
697 :
698 : // Creates a trait bound with a clone of this type path as its only element.
699 : std::unique_ptr<TraitBound> to_trait_bound (bool in_parens) const override;
700 :
701 : void accept_vis (HIRFullVisitor &vis) override;
702 : void accept_vis (HIRTypeVisitor &vis) override;
703 :
704 144108 : size_t get_num_segments () const { return segments.size (); }
705 :
706 50400 : std::vector<std::unique_ptr<TypePathSegment> > &get_segments ()
707 : {
708 96989 : return segments;
709 : }
710 :
711 6936 : TypePathSegment &get_final_segment () { return *segments.back (); }
712 : };
713 :
714 : class QualifiedPathType
715 : {
716 : std::unique_ptr<Type> type;
717 : std::unique_ptr<TypePath> trait;
718 : location_t locus;
719 : Analysis::NodeMapping mappings;
720 :
721 : public:
722 : // Constructor
723 : QualifiedPathType (Analysis::NodeMapping mappings, std::unique_ptr<Type> type,
724 : std::unique_ptr<TypePath> trait, location_t locus);
725 :
726 : // Copy constructor uses custom deep copy for Type to preserve polymorphism
727 : QualifiedPathType (QualifiedPathType const &other);
728 :
729 : // default destructor
730 1074 : ~QualifiedPathType () = default;
731 :
732 : // overload assignment operator to use custom clone method
733 : QualifiedPathType &operator= (QualifiedPathType const &other);
734 :
735 : // move constructor
736 600 : QualifiedPathType (QualifiedPathType &&other) = default;
737 : QualifiedPathType &operator= (QualifiedPathType &&other) = default;
738 :
739 : // Returns whether the qualified path type has a rebind as clause.
740 1138 : bool has_as_clause () const { return trait != nullptr; }
741 :
742 : std::string to_string () const;
743 :
744 : location_t get_locus () const { return locus; }
745 :
746 0 : Analysis::NodeMapping get_mappings () const { return mappings; }
747 :
748 0 : bool has_type () { return type != nullptr; }
749 0 : bool has_trait () { return trait != nullptr; }
750 :
751 950 : Type &get_type ()
752 : {
753 950 : rust_assert (type);
754 950 : return *type;
755 : }
756 :
757 804 : TypePath &get_trait ()
758 : {
759 804 : rust_assert (trait);
760 804 : return *trait;
761 : }
762 :
763 : bool trait_has_generic_args () const;
764 :
765 : GenericArgs &get_trait_generic_args ();
766 : };
767 :
768 : /* HIR node representing a qualified path-in-expression pattern (path that
769 : * allows specifying trait functions) */
770 : class QualifiedPathInExpression : public PathPattern, public PathExpr
771 : {
772 : QualifiedPathType path_type;
773 : location_t locus;
774 :
775 : public:
776 : std::string to_string () const override;
777 :
778 : QualifiedPathInExpression (Analysis::NodeMapping mappings,
779 : QualifiedPathType qual_path_type,
780 : std::vector<PathExprSegment> path_segments,
781 : location_t locus = UNDEF_LOCATION,
782 : std::vector<AST::Attribute> outer_attrs
783 : = std::vector<AST::Attribute> ());
784 :
785 : // lang-item constructor
786 : QualifiedPathInExpression (Analysis::NodeMapping mappings,
787 : QualifiedPathType qual_path_type,
788 : LangItem::Kind lang_item,
789 : location_t locus = UNDEF_LOCATION,
790 : std::vector<AST::Attribute> outer_attrs
791 : = std::vector<AST::Attribute> ());
792 :
793 155 : location_t get_locus () const override final { return locus; }
794 :
795 : void accept_vis (HIRFullVisitor &vis) override;
796 : void accept_vis (HIRExpressionVisitor &vis) override;
797 : void accept_vis (HIRPatternVisitor &vis) override;
798 :
799 188 : QualifiedPathType &get_path_type () { return path_type; }
800 :
801 220 : location_t get_locus () { return locus; }
802 :
803 334 : const Analysis::NodeMapping &get_mappings () const override final
804 : {
805 334 : return mappings;
806 : }
807 :
808 : protected:
809 : /* Use covariance to implement clone function as returning this object rather
810 : * than base */
811 0 : QualifiedPathInExpression *clone_pattern_impl () const override
812 : {
813 0 : return new QualifiedPathInExpression (*this);
814 : }
815 :
816 : /* Use covariance to implement clone function as returning this object rather
817 : * than base */
818 0 : QualifiedPathInExpression *clone_expr_without_block_impl () const override
819 : {
820 0 : return new QualifiedPathInExpression (*this);
821 : }
822 : };
823 :
824 : /* Represents a qualified path in a type; used for disambiguating trait function
825 : * calls */
826 : class QualifiedPathInType : public TypeNoBounds
827 : {
828 : QualifiedPathType path_type;
829 : std::unique_ptr<TypePathSegment> associated_segment;
830 : std::vector<std::unique_ptr<TypePathSegment> > segments;
831 :
832 : protected:
833 : /* Use covariance to implement clone function as returning this object rather
834 : * than base */
835 29 : QualifiedPathInType *clone_type_impl () const override
836 : {
837 29 : return new QualifiedPathInType (*this);
838 : }
839 :
840 : /* Use covariance to implement clone function as returning this object rather
841 : * than base */
842 0 : QualifiedPathInType *clone_type_no_bounds_impl () const override
843 : {
844 0 : return new QualifiedPathInType (*this);
845 : }
846 :
847 : public:
848 : QualifiedPathInType (
849 : Analysis::NodeMapping mappings, QualifiedPathType qual_path_type,
850 : std::unique_ptr<TypePathSegment> associated_segment,
851 : std::vector<std::unique_ptr<TypePathSegment> > path_segments,
852 : location_t locus = UNDEF_LOCATION);
853 :
854 : // Copy constructor with vector clone
855 : QualifiedPathInType (QualifiedPathInType const &other);
856 :
857 : // Overloaded assignment operator with vector clone
858 : QualifiedPathInType &operator= (QualifiedPathInType const &other);
859 :
860 : // move constructors
861 : QualifiedPathInType (QualifiedPathInType &&other) = default;
862 : QualifiedPathInType &operator= (QualifiedPathInType &&other) = default;
863 :
864 : std::string to_string () const override;
865 :
866 : void accept_vis (HIRFullVisitor &vis) override;
867 : void accept_vis (HIRTypeVisitor &vis) override;
868 :
869 441 : QualifiedPathType &get_path_type () { return path_type; }
870 :
871 440 : TypePathSegment &get_associated_segment () { return *associated_segment; }
872 :
873 1 : std::vector<std::unique_ptr<TypePathSegment> > &get_segments ()
874 : {
875 440 : return segments;
876 : }
877 : };
878 :
879 : } // namespace HIR
880 : } // namespace Rust
881 :
882 : #endif
|