Branch data Line data Source code
1 : : // Copyright (C) 2020-2025 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 : 156991 : 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 : 137748 : PathIdentSegment (std::string segment_name)
41 : 129033 : : segment_name (std::move (segment_name))
42 : : {}
43 : :
44 : 368240 : PathIdentSegment (const PathIdentSegment &other)
45 : 679739 : : 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 : 8715 : static PathIdentSegment create_error () { return PathIdentSegment (""); }
56 : :
57 : : // Returns whether PathIdentSegment is in an error state.
58 : 12941 : bool is_error () const { return segment_name.empty (); }
59 : :
60 : 656225 : std::string as_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 : 265 : ~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 : 75 : GenericArgsBinding (GenericArgsBinding &&other) = default;
100 : : GenericArgsBinding &operator= (GenericArgsBinding &&other) = default;
101 : :
102 : : std::string as_string () const;
103 : :
104 : : Identifier &get_identifier () { return identifier; }
105 : : const Identifier &get_identifier () const { return identifier; }
106 : :
107 : 72 : Type &get_type ()
108 : : {
109 : 72 : rust_assert (type);
110 : 72 : 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 : 184 : 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 : 62 : std::unique_ptr<Expr> &get_expression () { return expression; }
134 : :
135 : 62 : 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 : 56978 : bool has_generic_args () const
153 : : {
154 : 112269 : return !(lifetime_args.empty () && type_args.empty ()
155 : 55337 : && 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 : 231231 : ~GenericArgs () = default;
167 : :
168 : : // overloaded assignment operator to vector clone
169 : : GenericArgs &operator= (GenericArgs const &other);
170 : :
171 : : // move constructors
172 : 98325 : GenericArgs (GenericArgs &&other) = default;
173 : 5925 : GenericArgs &operator= (GenericArgs &&other) = default;
174 : :
175 : : // Creates an empty GenericArgs (no arguments)
176 : 66019 : static GenericArgs create_empty (location_t locus = UNDEF_LOCATION)
177 : : {
178 : 66019 : return GenericArgs ({}, {}, {}, {}, locus);
179 : : }
180 : :
181 : : bool is_empty () const;
182 : :
183 : : std::string as_string () const;
184 : :
185 : 5898 : std::vector<Lifetime> &get_lifetime_args () { return lifetime_args; }
186 : : const std::vector<Lifetime> &get_lifetime_args () const
187 : : {
188 : 9097 : return lifetime_args;
189 : : }
190 : :
191 : 9171 : std::vector<std::unique_ptr<Type> > &get_type_args () { return type_args; }
192 : :
193 : 5971 : std::vector<GenericArgsBinding> &get_binding_args () { return binding_args; }
194 : :
195 : 15002 : std::vector<ConstGenericArg> &get_const_args () { return const_args; }
196 : :
197 : 16144 : 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 : 152542 : 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 : 71448 : PathExprSegment (PathExprSegment &&other) = default;
221 : : PathExprSegment &operator= (PathExprSegment &&other) = default;
222 : :
223 : : std::string as_string () const;
224 : :
225 : 38909 : location_t get_locus () const { return locus; }
226 : :
227 : 46812 : PathIdentSegment &get_segment () { return segment_name; }
228 : 40977 : const PathIdentSegment &get_segment () const { return segment_name; }
229 : :
230 : : GenericArgs &get_generic_args () { return generic_args; }
231 : :
232 : 146977 : const Analysis::NodeMapping &get_mappings () const { return mappings; }
233 : :
234 : 56133 : 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 : 47989 : PathPattern (std::vector<PathExprSegment> segments)
254 : 47989 : : segments (std::move (segments)), lang_item (tl::nullopt),
255 : 47989 : kind (Kind::Segmented)
256 : 47989 : {}
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 : 4 : bool has_segments () const
264 : : {
265 : 4 : rust_assert (kind == Kind::Segmented);
266 : 4 : 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 as_string () const override;
284 : :
285 : : void iterate_path_segments (std::function<bool (PathExprSegment &)> cb);
286 : :
287 : 100645 : size_t get_num_segments () const
288 : : {
289 : 100645 : rust_assert (kind == Kind::Segmented);
290 : 100645 : return segments.size ();
291 : : }
292 : :
293 : 104560 : std::vector<PathExprSegment> &get_segments ()
294 : : {
295 : 104560 : rust_assert (kind == Kind::Segmented);
296 : 104560 : 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 : 40984 : const PathExprSegment &get_final_segment () const
312 : : {
313 : 40984 : rust_assert (kind == Kind::Segmented);
314 : 40984 : 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 : 740 : PatternType get_pattern_type () const override final
325 : : {
326 : 740 : return PatternType::PATH;
327 : : }
328 : :
329 : 174258 : 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 as_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 : 4 : 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 : 4 : return convert_to_simple_path (has_opening_scope_resolution);
379 : : }
380 : :
381 : 206734 : 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 : 168283 : const Analysis::NodeMapping &get_mappings () const override final
392 : : {
393 : 163464 : return mappings;
394 : : }
395 : :
396 : : protected:
397 : : /* Use covariance to implement clone function as returning this object rather
398 : : * than base */
399 : 825 : PathInExpression *clone_pattern_impl () const override
400 : : {
401 : 825 : return new PathInExpression (*this);
402 : : }
403 : :
404 : : /* Use covariance to implement clone function as returning this object rather
405 : : * than base */
406 : 785 : PathInExpression *clone_expr_without_block_impl () const override
407 : : {
408 : 785 : 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 : 13662 : virtual TypePathSegment *clone_type_path_segment_impl () const
437 : : {
438 : 13662 : return new TypePathSegment (*this);
439 : : }
440 : :
441 : : public:
442 : 23502 : virtual ~TypePathSegment () {}
443 : :
444 : 50864 : virtual SegmentType get_type () const { return SegmentType::REG; }
445 : :
446 : : // Unique pointer custom clone function
447 : 14643 : std::unique_ptr<TypePathSegment> clone_type_path_segment () const
448 : : {
449 : 14643 : 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 : 94188 : virtual std::string as_string () const
463 : : {
464 : 94188 : if (ident_segment)
465 : 94141 : return ident_segment->as_string ();
466 : :
467 : 47 : 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 : 44147 : virtual bool is_ident_only () const { return true; }
481 : :
482 : 88 : 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 : 46999 : const Analysis::NodeMapping &get_mappings () const { return mappings; }
488 : :
489 : 546 : const PathIdentSegment &get_ident_segment () const
490 : : {
491 : 546 : rust_assert (ident_segment);
492 : 546 : return *ident_segment;
493 : : }
494 : :
495 : 47 : const LangItem::Kind &get_lang_item () const
496 : : {
497 : 47 : rust_assert (lang_item);
498 : 47 : return *lang_item;
499 : : }
500 : :
501 : 46660 : bool is_generic_segment () const
502 : : {
503 : 46660 : return get_type () == SegmentType::GENERIC;
504 : : }
505 : :
506 : 46969 : 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 : 845 : bool has_generic_args () const { return generic_args.has_generic_args (); }
516 : :
517 : 1851 : 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 as_string () const override;
540 : :
541 : : void accept_vis (HIRFullVisitor &vis) override;
542 : :
543 : 1851 : GenericArgs &get_generic_args () { return generic_args; }
544 : :
545 : 2696 : virtual SegmentType get_type () const override final
546 : : {
547 : 2696 : return SegmentType::GENERIC;
548 : : }
549 : :
550 : : // Use covariance to override base class method
551 : 980 : TypePathSegmentGeneric *clone_type_path_segment_impl () const override
552 : : {
553 : 980 : 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 : 57 : bool has_return_type () const { return return_type != nullptr; }
566 : :
567 : : // Returns whether the function has inputs.
568 : 0 : 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 as_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 : 54 : 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 as_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 : 27 : 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 : 3032 : 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 : 12707 : 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 : 3032 : TypePath (TypePath &&other) = default;
684 : : TypePath &operator= (TypePath &&other) = default;
685 : :
686 : : std::string as_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 : 137012 : size_t get_num_segments () const { return segments.size (); }
699 : :
700 : 47943 : std::vector<std::unique_ptr<TypePathSegment> > &get_segments ()
701 : : {
702 : 47943 : return segments;
703 : : }
704 : :
705 : 6694 : 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 : 1047 : ~QualifiedPathType () = default;
725 : :
726 : : // overload assignment operator to use custom clone method
727 : : QualifiedPathType &operator= (QualifiedPathType const &other);
728 : :
729 : : // move constructor
730 : 584 : QualifiedPathType (QualifiedPathType &&other) = default;
731 : : QualifiedPathType &operator= (QualifiedPathType &&other) = default;
732 : :
733 : : // Returns whether the qualified path type has a rebind as clause.
734 : 847 : bool has_as_clause () const { return trait != nullptr; }
735 : :
736 : : std::string as_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 : 663 : Type &get_type ()
746 : : {
747 : 663 : rust_assert (type);
748 : 663 : return *type;
749 : : }
750 : :
751 : 549 : TypePath &get_trait ()
752 : : {
753 : 549 : rust_assert (trait);
754 : 549 : 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 as_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 : 114 : 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 as_string () const override;
859 : :
860 : : void accept_vis (HIRFullVisitor &vis) override;
861 : : void accept_vis (HIRTypeVisitor &vis) override;
862 : :
863 : 235 : QualifiedPathType &get_path_type () { return path_type; }
864 : :
865 : 234 : TypePathSegment &get_associated_segment () { return *associated_segment; }
866 : :
867 : 1 : std::vector<std::unique_ptr<TypePathSegment> > &get_segments ()
868 : : {
869 : 234 : return segments;
870 : : }
871 : : };
872 : :
873 : : } // namespace HIR
874 : : } // namespace Rust
875 : :
876 : : #endif
|