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