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_TYTY
20 : : #define RUST_TYTY
21 : :
22 : : #include "rust-hir-map.h"
23 : : #include "rust-common.h"
24 : : #include "rust-identifier.h"
25 : : #include "rust-abi.h"
26 : : #include "rust-tyty-bounds.h"
27 : : #include "rust-tyty-util.h"
28 : : #include "rust-tyty-subst.h"
29 : : #include "rust-tyty-region.h"
30 : : #include "rust-system.h"
31 : : #include "rust-hir.h"
32 : :
33 : : namespace Rust {
34 : :
35 : : namespace Resolver {
36 : : class TraitReference;
37 : :
38 : : class TraitItemReference;
39 : :
40 : : class AssociatedImplTrait;
41 : : } // namespace Resolver
42 : :
43 : : namespace TyTy {
44 : : class ClosureType;
45 : : class FnPtr;
46 : : class FnType;
47 : : class CallableTypeInterface;
48 : :
49 : : // https://rustc-dev-guide.rust-lang.org/type-inference.html#inference-variables
50 : : // https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html#variants
51 : : enum TypeKind
52 : : {
53 : : INFER,
54 : : ADT,
55 : : STR,
56 : : REF,
57 : : POINTER,
58 : : PARAM,
59 : : ARRAY,
60 : : SLICE,
61 : : FNDEF,
62 : : FNPTR,
63 : : TUPLE,
64 : : BOOL,
65 : : CHAR,
66 : : INT,
67 : : UINT,
68 : : FLOAT,
69 : : USIZE,
70 : : ISIZE,
71 : : NEVER,
72 : : PLACEHOLDER,
73 : : PROJECTION,
74 : : DYNAMIC,
75 : : CLOSURE,
76 : : OPAQUE,
77 : : // there are more to add...
78 : : ERROR
79 : : };
80 : :
81 : : extern bool
82 : : is_primitive_type_kind (TypeKind kind);
83 : :
84 : : class TypeKindFormat
85 : : {
86 : : public:
87 : : static std::string to_string (TypeKind kind);
88 : : };
89 : :
90 : : class TyVisitor;
91 : : class TyConstVisitor;
92 : : class BaseType : public TypeBoundsMappings
93 : : {
94 : : public:
95 : : virtual ~BaseType ();
96 : :
97 : : HirId get_ref () const;
98 : : void set_ref (HirId id);
99 : :
100 : : HirId get_ty_ref () const;
101 : : void set_ty_ref (HirId id);
102 : :
103 : : HirId get_orig_ref () const;
104 : :
105 : : virtual void accept_vis (TyVisitor &vis) = 0;
106 : : virtual void accept_vis (TyConstVisitor &vis) const = 0;
107 : :
108 : : virtual std::string as_string () const = 0;
109 : : virtual std::string get_name () const = 0;
110 : :
111 : : // similar to unify but does not actually perform type unification but
112 : : // determines whether they are compatible. Consider the following
113 : : //
114 : : // fn foo<T>() -> T { ... }
115 : : // fn foo() -> i32 { ... }
116 : : //
117 : : // when the function has been substituted they can be considered equal.
118 : : //
119 : : // It can also be used to optional emit errors for trait item compatibility
120 : : // checks
121 : : virtual bool can_eq (const BaseType *other, bool emit_errors) const = 0;
122 : :
123 : : // Check value equality between two ty. Type inference rules are ignored. Two
124 : : // ty are considered equal if they're of the same kind, and
125 : : // 1. (For ADTs, arrays, tuples, refs) have the same underlying ty
126 : : // 2. (For functions) have the same signature
127 : : virtual bool is_equal (const BaseType &other) const;
128 : :
129 : : bool satisfies_bound (const TypeBoundPredicate &predicate,
130 : : bool emit_error) const;
131 : :
132 : : bool bounds_compatible (const BaseType &other, location_t locus,
133 : : bool emit_error) const;
134 : :
135 : : void inherit_bounds (const BaseType &other);
136 : :
137 : : void inherit_bounds (
138 : : const std::vector<TyTy::TypeBoundPredicate> &specified_bounds);
139 : :
140 : : // contains_infer checks if there is an inference variable inside the type
141 : : const TyTy::BaseType *contains_infer () const;
142 : :
143 : : // is_unit returns whether this is just a unit-struct
144 : : bool is_unit () const;
145 : :
146 : : // is_concrete returns true if the type is fully resolved to concrete
147 : : // primitives
148 : : bool is_concrete () const;
149 : :
150 : : // return the type-kind
151 : : TypeKind get_kind () const;
152 : :
153 : : // monomorphized clone is a clone which destructures the types to get rid of
154 : : // generics
155 : : BaseType *monomorphized_clone () const;
156 : :
157 : : // get_combined_refs returns the chain of node refs involved in unification
158 : : std::set<HirId> get_combined_refs () const;
159 : :
160 : : void append_reference (HirId id);
161 : :
162 : : std::string mappings_str () const;
163 : :
164 : : std::string debug_str () const;
165 : :
166 : : void debug () const;
167 : :
168 : : // FIXME this will eventually go away
169 : : const BaseType *get_root () const;
170 : :
171 : : // This will get the monomorphized type from Params, Placeholders or
172 : : // Projections if available or error
173 : : BaseType *destructure ();
174 : : const BaseType *destructure () const;
175 : :
176 : : const RustIdent &get_ident () const;
177 : : location_t get_locus () const;
178 : :
179 : : bool has_substitutions_defined () const;
180 : : bool needs_generic_substitutions () const;
181 : : const SubstitutionArgumentMappings &get_subst_argument_mappings () const;
182 : :
183 : 28488 : std::string mangle_string () const
184 : : {
185 : 85464 : return TypeKindFormat::to_string (get_kind ()) + ":" + as_string () + ":"
186 : 113952 : + mappings_str () + ":" + bounds_as_string ();
187 : : }
188 : :
189 : : /* Returns a pointer to a clone of this. The caller is responsible for
190 : : * releasing the memory of the returned ty. */
191 : : virtual BaseType *clone () const = 0;
192 : :
193 : : // Check if TyTy::BaseType is of a specific type.
194 : 10129047 : template <typename T> WARN_UNUSED_RESULT bool is () const
195 : : {
196 : : static_assert (std::is_base_of<BaseType, T>::value,
197 : : "Can only safely cast to TyTy types.");
198 : 1666262 : return this->get_kind () == T::KIND;
199 : : }
200 : :
201 : 129405 : template <typename T> T *as () const
202 : : {
203 : : static_assert (std::is_base_of<BaseType, T>::value,
204 : : "Can only safely cast to TyTy types.");
205 : 129405 : rust_assert (this->is<T> ());
206 : 129405 : return static_cast<T *> (this);
207 : : }
208 : :
209 : 6573 : template <typename T> T *as ()
210 : : {
211 : : static_assert (std::is_base_of<BaseType, T>::value,
212 : : "Can only safely cast to TyTy types.");
213 : 6573 : rust_assert (this->is<T> ());
214 : 6573 : return static_cast<T *> (this);
215 : : }
216 : :
217 : : // Check if TyTy::BaseType is of a specific type and convert it to that type
218 : : // if so.
219 : : // Returns nullptr otherwise. Works as a dynamic_cast, but without compiler
220 : : // RTTI.
221 : 5548166 : template <typename T> T *try_as () const
222 : : {
223 : : static_assert (std::is_base_of<BaseType, T>::value,
224 : : "Can only safely cast to TyTy types.");
225 : 5548166 : if (!this->is<T> ())
226 : : return nullptr;
227 : :
228 : : return static_cast<T *> (this);
229 : : }
230 : :
231 : : // See above.
232 : 2825980 : template <typename T> T *try_as ()
233 : : {
234 : : static_assert (std::is_base_of<BaseType, T>::value,
235 : : "Can only safely cast to TyTy types.");
236 : 2825980 : if (!this->is<T> ())
237 : 0 : return nullptr;
238 : :
239 : : return static_cast<T *> (this);
240 : : }
241 : :
242 : : protected:
243 : : BaseType (HirId ref, HirId ty_ref, TypeKind kind, RustIdent ident,
244 : : std::set<HirId> refs = std::set<HirId> ());
245 : :
246 : : BaseType (HirId ref, HirId ty_ref, TypeKind kind, RustIdent ident,
247 : : std::vector<TypeBoundPredicate> specified_bounds,
248 : : std::set<HirId> refs = std::set<HirId> ());
249 : :
250 : : TypeKind kind;
251 : : HirId ref;
252 : : HirId ty_ref;
253 : : const HirId orig_ref;
254 : : std::set<HirId> combined;
255 : : RustIdent ident;
256 : :
257 : : Analysis::Mappings &mappings;
258 : : };
259 : :
260 : : /** Unified interface for all function-like types. */
261 : : class CallableTypeInterface : public BaseType
262 : : {
263 : : public:
264 : 38161 : explicit CallableTypeInterface (HirId ref, HirId ty_ref, TypeKind kind,
265 : : RustIdent ident,
266 : : std::set<HirId> refs = std::set<HirId> ())
267 : 38161 : : BaseType (ref, ty_ref, kind, ident, refs)
268 : 38161 : {}
269 : :
270 : : WARN_UNUSED_RESULT virtual size_t get_num_params () const = 0;
271 : : WARN_UNUSED_RESULT virtual BaseType *
272 : : get_param_type_at (size_t index) const = 0;
273 : : WARN_UNUSED_RESULT virtual BaseType *get_return_type () const = 0;
274 : : };
275 : :
276 : : class InferType : public BaseType
277 : : {
278 : : public:
279 : : static constexpr auto KIND = TypeKind::INFER;
280 : :
281 : : enum InferTypeKind
282 : : {
283 : : GENERAL,
284 : : INTEGRAL,
285 : : FLOAT
286 : : };
287 : :
288 : : struct TypeHint
289 : : {
290 : : enum SignedHint
291 : : {
292 : : SIGNED,
293 : : UNSIGNED,
294 : :
295 : : UNKNOWN
296 : : };
297 : : enum SizeHint
298 : : {
299 : : S8,
300 : : S16,
301 : : S32,
302 : : S64,
303 : : S128,
304 : : SUNKNOWN
305 : : };
306 : :
307 : : TyTy::TypeKind kind;
308 : : SignedHint shint;
309 : : SizeHint szhint;
310 : :
311 : : static TypeHint Default ()
312 : : {
313 : : return TypeHint{TypeKind::ERROR, UNKNOWN, SUNKNOWN};
314 : : }
315 : : };
316 : :
317 : : InferType (HirId ref, InferTypeKind infer_kind, TypeHint hint,
318 : : location_t locus, std::set<HirId> refs = std::set<HirId> ());
319 : :
320 : : InferType (HirId ref, HirId ty_ref, InferTypeKind infer_kind, TypeHint hint,
321 : : location_t locus, std::set<HirId> refs = std::set<HirId> ());
322 : :
323 : : void accept_vis (TyVisitor &vis) override;
324 : :
325 : : void accept_vis (TyConstVisitor &vis) const override;
326 : :
327 : : std::string as_string () const override;
328 : :
329 : : bool can_eq (const BaseType *other, bool emit_errors) const override final;
330 : :
331 : : BaseType *clone () const final override;
332 : :
333 : : InferTypeKind get_infer_kind () const;
334 : :
335 : : std::string get_name () const override final;
336 : :
337 : : bool default_type (BaseType **type) const;
338 : :
339 : : void apply_primitive_type_hint (const TyTy::BaseType &hint);
340 : :
341 : : private:
342 : : InferTypeKind infer_kind;
343 : : TypeHint default_hint;
344 : : };
345 : :
346 : : class ErrorType : public BaseType
347 : : {
348 : : public:
349 : : static constexpr auto KIND = TypeKind::ERROR;
350 : :
351 : : ErrorType (HirId ref, std::set<HirId> refs = std::set<HirId> ());
352 : :
353 : : ErrorType (HirId ref, HirId ty_ref,
354 : : std::set<HirId> refs = std::set<HirId> ());
355 : :
356 : : void accept_vis (TyVisitor &vis) override;
357 : : void accept_vis (TyConstVisitor &vis) const override;
358 : :
359 : : std::string as_string () const override;
360 : :
361 : : bool can_eq (const BaseType *other, bool emit_errors) const override final;
362 : :
363 : : BaseType *clone () const final override;
364 : :
365 : : std::string get_name () const override final;
366 : : };
367 : :
368 : : class ParamType : public BaseType
369 : : {
370 : : public:
371 : : static constexpr auto KIND = TypeKind::PARAM;
372 : :
373 : : ParamType (std::string symbol, location_t locus, HirId ref,
374 : : HIR::GenericParam ¶m,
375 : : std::vector<TypeBoundPredicate> specified_bounds,
376 : : std::set<HirId> refs = std::set<HirId> ());
377 : :
378 : : ParamType (bool is_trait_self, std::string symbol, location_t locus,
379 : : HirId ref, HirId ty_ref, HIR::GenericParam ¶m,
380 : : std::vector<TypeBoundPredicate> specified_bounds,
381 : : std::set<HirId> refs = std::set<HirId> ());
382 : :
383 : : void accept_vis (TyVisitor &vis) override;
384 : : void accept_vis (TyConstVisitor &vis) const override;
385 : :
386 : : std::string as_string () const override;
387 : :
388 : : bool can_eq (const BaseType *other, bool emit_errors) const override final;
389 : :
390 : : BaseType *clone () const final override;
391 : :
392 : : std::string get_symbol () const;
393 : :
394 : : HIR::GenericParam &get_generic_param ();
395 : :
396 : : bool can_resolve () const;
397 : :
398 : : BaseType *resolve () const;
399 : :
400 : : std::string get_name () const override final;
401 : :
402 : : bool is_equal (const BaseType &other) const override;
403 : :
404 : : ParamType *handle_substitions (SubstitutionArgumentMappings &mappings);
405 : :
406 : : void set_implicit_self_trait ();
407 : : bool is_implicit_self_trait () const;
408 : :
409 : : private:
410 : : bool is_trait_self;
411 : : std::string symbol;
412 : : HIR::GenericParam ¶m;
413 : : };
414 : :
415 : 0 : class OpaqueType : public BaseType
416 : : {
417 : : public:
418 : : static constexpr auto KIND = TypeKind::OPAQUE;
419 : :
420 : : OpaqueType (location_t locus, HirId ref,
421 : : std::vector<TypeBoundPredicate> specified_bounds,
422 : : std::set<HirId> refs = std::set<HirId> ());
423 : :
424 : : OpaqueType (location_t locus, HirId ref, HirId ty_ref,
425 : : std::vector<TypeBoundPredicate> specified_bounds,
426 : : std::set<HirId> refs = std::set<HirId> ());
427 : :
428 : : void accept_vis (TyVisitor &vis) override;
429 : : void accept_vis (TyConstVisitor &vis) const override;
430 : :
431 : : std::string as_string () const override;
432 : :
433 : : bool can_eq (const BaseType *other, bool emit_errors) const override final;
434 : :
435 : : BaseType *clone () const final override;
436 : :
437 : : bool can_resolve () const;
438 : :
439 : : BaseType *resolve () const;
440 : :
441 : : std::string get_name () const override final;
442 : :
443 : : bool is_equal (const BaseType &other) const override;
444 : :
445 : : OpaqueType *handle_substitions (SubstitutionArgumentMappings &mappings);
446 : : };
447 : :
448 : : class StructFieldType
449 : : {
450 : : public:
451 : : StructFieldType (HirId ref, std::string name, BaseType *ty, location_t locus);
452 : :
453 : : HirId get_ref () const;
454 : :
455 : : bool is_equal (const StructFieldType &other) const;
456 : :
457 : : std::string get_name () const;
458 : :
459 : : BaseType *get_field_type () const;
460 : : void set_field_type (BaseType *fty);
461 : :
462 : : StructFieldType *clone () const;
463 : : StructFieldType *monomorphized_clone () const;
464 : :
465 : : void debug () const;
466 : : location_t get_locus () const;
467 : : std::string as_string () const;
468 : :
469 : : private:
470 : : HirId ref;
471 : : std::string name;
472 : : BaseType *ty;
473 : : location_t locus;
474 : : };
475 : :
476 : : class TupleType : public BaseType
477 : : {
478 : : public:
479 : : static constexpr auto KIND = TypeKind::TUPLE;
480 : :
481 : : TupleType (HirId ref, location_t locus,
482 : : std::vector<TyVar> fields = std::vector<TyVar> (),
483 : : std::set<HirId> refs = std::set<HirId> ());
484 : :
485 : : TupleType (HirId ref, HirId ty_ref, location_t locus,
486 : : std::vector<TyVar> fields = std::vector<TyVar> (),
487 : : std::set<HirId> refs = std::set<HirId> ());
488 : :
489 : : static TupleType *get_unit_type ();
490 : :
491 : : void accept_vis (TyVisitor &vis) override;
492 : : void accept_vis (TyConstVisitor &vis) const override;
493 : :
494 : : std::string as_string () const override;
495 : :
496 : : bool can_eq (const BaseType *other, bool emit_errors) const override final;
497 : :
498 : : bool is_equal (const BaseType &other) const override;
499 : :
500 : : size_t num_fields () const;
501 : :
502 : : BaseType *get_field (size_t index) const;
503 : :
504 : : BaseType *clone () const final override;
505 : :
506 : : const std::vector<TyVar> &get_fields () const;
507 : :
508 : : std::string get_name () const override final;
509 : :
510 : : TupleType *handle_substitions (SubstitutionArgumentMappings &mappings);
511 : :
512 : : private:
513 : : std::vector<TyVar> fields;
514 : : };
515 : :
516 : : class TypeBoundPredicate : public SubstitutionRef
517 : : {
518 : : public:
519 : : TypeBoundPredicate (const Resolver::TraitReference &trait_reference,
520 : : BoundPolarity polarity, location_t locus);
521 : :
522 : : TypeBoundPredicate (DefId reference,
523 : : std::vector<SubstitutionParamMapping> substitutions,
524 : : BoundPolarity polarity, location_t locus);
525 : :
526 : : TypeBoundPredicate (const TypeBoundPredicate &other);
527 : :
528 : 23841500 : virtual ~TypeBoundPredicate (){};
529 : :
530 : : TypeBoundPredicate &operator= (const TypeBoundPredicate &other);
531 : :
532 : : static TypeBoundPredicate error ();
533 : :
534 : : std::string as_string () const;
535 : :
536 : : std::string as_name () const;
537 : :
538 : : const Resolver::TraitReference *get () const;
539 : :
540 : 2686 : location_t get_locus () const { return locus; }
541 : :
542 : : std::string get_name () const;
543 : :
544 : : // check that this predicate is object-safe see:
545 : : // https://doc.rust-lang.org/reference/items/traits.html#object-safety
546 : : bool is_object_safe (bool emit_error, location_t locus) const;
547 : :
548 : : void apply_generic_arguments (HIR::GenericArgs *generic_args,
549 : : bool has_associated_self);
550 : :
551 : : void apply_argument_mappings (SubstitutionArgumentMappings &arguments);
552 : :
553 : : bool contains_item (const std::string &search) const;
554 : :
555 : : TypeBoundPredicateItem
556 : : lookup_associated_item (const std::string &search) const;
557 : :
558 : : TypeBoundPredicateItem
559 : : lookup_associated_item (const Resolver::TraitItemReference *ref) const;
560 : :
561 : : // WARNING THIS WILL ALWAYS RETURN NULLPTR
562 : : BaseType *
563 : : handle_substitions (SubstitutionArgumentMappings &mappings) override final;
564 : :
565 : : bool is_error () const;
566 : :
567 : : bool requires_generic_args () const;
568 : :
569 : : bool contains_associated_types () const;
570 : :
571 : 30772 : DefId get_id () const { return reference; }
572 : :
573 : 10752 : BoundPolarity get_polarity () const { return polarity; }
574 : :
575 : : std::vector<TypeBoundPredicateItem> get_associated_type_items ();
576 : :
577 : : size_t get_num_associated_bindings () const override final;
578 : :
579 : : TypeBoundPredicateItem
580 : : lookup_associated_type (const std::string &search) override final;
581 : :
582 : : bool is_equal (const TypeBoundPredicate &other) const;
583 : :
584 : : bool validate_type_implements_super_traits (TyTy::BaseType &self,
585 : : HIR::Type &impl_type,
586 : : HIR::Type &trait) const;
587 : :
588 : : bool validate_type_implements_this (TyTy::BaseType &self,
589 : : HIR::Type &impl_type,
590 : : HIR::Type &trait) const;
591 : :
592 : : private:
593 : : struct mark_is_error
594 : : {
595 : : };
596 : :
597 : : TypeBoundPredicate (mark_is_error);
598 : :
599 : : DefId reference;
600 : : location_t locus;
601 : : bool error_flag;
602 : : BoundPolarity polarity;
603 : : std::vector<TyTy::TypeBoundPredicate> super_traits;
604 : : };
605 : :
606 : 16176 : class TypeBoundPredicateItem
607 : : {
608 : : public:
609 : : TypeBoundPredicateItem (const TypeBoundPredicate parent,
610 : : const Resolver::TraitItemReference *trait_item_ref);
611 : :
612 : : TypeBoundPredicateItem (const TypeBoundPredicateItem &other);
613 : :
614 : : TypeBoundPredicateItem &operator= (const TypeBoundPredicateItem &other);
615 : :
616 : : static TypeBoundPredicateItem error ();
617 : :
618 : : bool is_error () const;
619 : :
620 : : BaseType *get_tyty_for_receiver (const TyTy::BaseType *receiver);
621 : :
622 : : const Resolver::TraitItemReference *get_raw_item () const;
623 : :
624 : : bool needs_implementation () const;
625 : :
626 : : const TypeBoundPredicate *get_parent () const;
627 : :
628 : : location_t get_locus () const;
629 : :
630 : : private:
631 : : TypeBoundPredicate parent;
632 : : const Resolver::TraitItemReference *trait_item_ref;
633 : : };
634 : :
635 : : // https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.VariantDef.html
636 : : class VariantDef
637 : : {
638 : : public:
639 : : enum VariantType
640 : : {
641 : : NUM,
642 : : TUPLE,
643 : : STRUCT
644 : : };
645 : :
646 : : static std::string variant_type_string (VariantType type);
647 : :
648 : : VariantDef (HirId id, DefId defid, std::string identifier, RustIdent ident,
649 : : tl::optional<std::unique_ptr<HIR::Expr>> &&discriminant);
650 : :
651 : : VariantDef (HirId id, DefId defid, std::string identifier, RustIdent ident,
652 : : VariantType type,
653 : : tl::optional<std::unique_ptr<HIR::Expr>> &&discriminant,
654 : : std::vector<StructFieldType *> fields);
655 : :
656 : : static VariantDef &get_error_node ();
657 : : bool is_error () const;
658 : :
659 : : HirId get_id () const;
660 : : DefId get_defid () const;
661 : :
662 : : VariantType get_variant_type () const;
663 : : bool is_data_variant () const;
664 : : bool is_dataless_variant () const;
665 : :
666 : : std::string get_identifier () const;
667 : :
668 : : size_t num_fields () const;
669 : : StructFieldType *get_field_at_index (size_t index);
670 : :
671 : : std::vector<StructFieldType *> &get_fields ();
672 : :
673 : : bool lookup_field (const std::string &lookup, StructFieldType **field_lookup,
674 : : size_t *index) const;
675 : :
676 : : bool has_discriminant () const;
677 : :
678 : : HIR::Expr &get_discriminant ();
679 : : const HIR::Expr &get_discriminant () const;
680 : :
681 : : std::string as_string () const;
682 : :
683 : : bool is_equal (const VariantDef &other) const;
684 : :
685 : : VariantDef *clone () const;
686 : :
687 : : VariantDef *monomorphized_clone () const;
688 : :
689 : : const RustIdent &get_ident () const;
690 : :
691 : : private:
692 : : HirId id;
693 : : DefId defid;
694 : : std::string identifier;
695 : : RustIdent ident;
696 : : VariantType type;
697 : :
698 : : // can either be a structure or a discriminant value
699 : : tl::optional<std::unique_ptr<HIR::Expr>> discriminant;
700 : :
701 : : std::vector<StructFieldType *> fields;
702 : : };
703 : :
704 : : class ADTType : public BaseType, public SubstitutionRef
705 : : {
706 : : public:
707 : : static constexpr auto KIND = TypeKind::ADT;
708 : :
709 : : enum ADTKind
710 : : {
711 : : STRUCT_STRUCT,
712 : : TUPLE_STRUCT,
713 : : UNION,
714 : : ENUM
715 : : };
716 : :
717 : : enum ReprKind
718 : : {
719 : : RUST,
720 : : C,
721 : : INT,
722 : : ALIGN,
723 : : PACKED,
724 : : // TRANSPARENT,
725 : : // SIMD,
726 : : // ...
727 : : };
728 : :
729 : : // Representation options, specified via attributes e.g. #[repr(packed)]
730 : 104 : struct ReprOptions
731 : : {
732 : : ReprKind repr_kind = ReprKind::RUST;
733 : :
734 : : // For align and pack: 0 = unspecified. Nonzero = byte alignment.
735 : : // It is an error for both to be nonzero, this should be caught when
736 : : // parsing the #[repr] attribute.
737 : : unsigned char align = 0;
738 : : unsigned char pack = 0;
739 : : BaseType *repr = nullptr;
740 : : };
741 : :
742 : : ADTType (DefId id, HirId ref, std::string identifier, RustIdent ident,
743 : : ADTKind adt_kind, std::vector<VariantDef *> variants,
744 : : std::vector<SubstitutionParamMapping> subst_refs,
745 : : SubstitutionArgumentMappings generic_arguments
746 : : = SubstitutionArgumentMappings::error (),
747 : : RegionConstraints region_constraints = RegionConstraints{},
748 : : std::set<HirId> refs = std::set<HirId> ());
749 : :
750 : : ADTType (DefId id, HirId ref, HirId ty_ref, std::string identifier,
751 : : RustIdent ident, ADTKind adt_kind,
752 : : std::vector<VariantDef *> variants,
753 : : std::vector<SubstitutionParamMapping> subst_refs,
754 : : SubstitutionArgumentMappings generic_arguments
755 : : = SubstitutionArgumentMappings::error (),
756 : : RegionConstraints region_constraints = RegionConstraints{},
757 : : std::set<HirId> refs = std::set<HirId> ());
758 : :
759 : : ADTType (DefId id, HirId ref, HirId ty_ref, std::string identifier,
760 : : RustIdent ident, ADTKind adt_kind,
761 : : std::vector<VariantDef *> variants,
762 : : std::vector<SubstitutionParamMapping> subst_refs, ReprOptions repr,
763 : : SubstitutionArgumentMappings generic_arguments
764 : : = SubstitutionArgumentMappings::error (),
765 : : RegionConstraints region_constraints = RegionConstraints{},
766 : : std::set<HirId> refs = std::set<HirId> ());
767 : :
768 : 117708 : ADTKind get_adt_kind () const { return adt_kind; }
769 : :
770 : 93881 : ReprOptions get_repr_options () const { return repr; }
771 : :
772 : 354 : bool is_struct_struct () const { return adt_kind == STRUCT_STRUCT; }
773 : :
774 : 0 : bool is_tuple_struct () const { return adt_kind == TUPLE_STRUCT; }
775 : :
776 : 13850 : bool is_union () const { return adt_kind == UNION; }
777 : :
778 : 75016 : bool is_enum () const { return adt_kind == ENUM; }
779 : :
780 : : void accept_vis (TyVisitor &vis) override;
781 : :
782 : : void accept_vis (TyConstVisitor &vis) const override;
783 : :
784 : : std::string as_string () const override;
785 : :
786 : : bool can_eq (const BaseType *other, bool emit_errors) const override final;
787 : :
788 : : bool is_equal (const BaseType &other) const override;
789 : :
790 : 71446 : std::string get_identifier () const { return identifier; }
791 : :
792 : 113484 : std::string get_name () const override final
793 : : {
794 : 113484 : return identifier + subst_as_string ();
795 : : }
796 : :
797 : : DefId get_id () const;
798 : :
799 : : BaseType *clone () const final override;
800 : :
801 : 171456 : size_t number_of_variants () const { return variants.size (); }
802 : :
803 : 36659 : std::vector<VariantDef *> &get_variants () { return variants; }
804 : :
805 : 94884 : const std::vector<VariantDef *> &get_variants () const { return variants; }
806 : :
807 : 77 : bool lookup_variant (const std::string &lookup,
808 : : VariantDef **found_variant) const
809 : : {
810 : 123 : for (auto &variant : variants)
811 : : {
812 : 117 : if (variant->get_identifier ().compare (lookup) == 0)
813 : : {
814 : 71 : *found_variant = variant;
815 : 71 : return true;
816 : : }
817 : : }
818 : : return false;
819 : : }
820 : :
821 : 3410 : bool lookup_variant_by_id (HirId id, VariantDef **found_variant,
822 : : int *index = nullptr) const
823 : : {
824 : 3410 : int i = 0;
825 : 5927 : for (auto &variant : variants)
826 : : {
827 : 5927 : if (variant->get_id () == id)
828 : : {
829 : 3410 : if (index != nullptr)
830 : 1844 : *index = i;
831 : :
832 : 3410 : *found_variant = variant;
833 : 3410 : return true;
834 : : }
835 : 2517 : i++;
836 : : }
837 : : return false;
838 : : }
839 : :
840 : : ADTType *
841 : : handle_substitions (SubstitutionArgumentMappings &mappings) override final;
842 : :
843 : : private:
844 : : DefId id;
845 : : std::string identifier;
846 : : std::vector<VariantDef *> variants;
847 : : ADTType::ADTKind adt_kind;
848 : : ReprOptions repr;
849 : : };
850 : :
851 : 56662 : class FnParam
852 : : {
853 : : public:
854 : 43209 : FnParam (std::unique_ptr<HIR::Pattern> pattern, BaseType *type)
855 : 43209 : : pattern (std::move (pattern)), type (type)
856 : : {}
857 : :
858 : : FnParam (const FnParam &) = delete;
859 : 56662 : FnParam (FnParam &&) = default;
860 : : FnParam &operator= (FnParam &&) = default;
861 : :
862 : 12888 : HIR::Pattern &get_pattern () { return *pattern; }
863 : 78885 : const HIR::Pattern &get_pattern () const { return *pattern; }
864 : :
865 : 9717 : bool has_pattern () { return pattern != nullptr; }
866 : 134715 : BaseType *get_type () const { return type; }
867 : 7917 : void set_type (BaseType *new_type) { type = new_type; }
868 : :
869 : 17425 : FnParam clone () const
870 : : {
871 : 17425 : return FnParam (pattern->clone_pattern (), type->clone ());
872 : : }
873 : :
874 : 0 : FnParam monomorphized_clone () const
875 : : {
876 : 0 : return FnParam (pattern->clone_pattern (), type->monomorphized_clone ());
877 : : }
878 : :
879 : : private:
880 : : std::unique_ptr<HIR::Pattern> pattern;
881 : : BaseType *type;
882 : : };
883 : :
884 : : class FnType : public CallableTypeInterface, public SubstitutionRef
885 : : {
886 : : public:
887 : : static constexpr auto KIND = TypeKind::FNDEF;
888 : :
889 : : static const uint8_t FNTYPE_DEFAULT_FLAGS = 0x00;
890 : : static const uint8_t FNTYPE_IS_METHOD_FLAG = 0x01;
891 : : static const uint8_t FNTYPE_IS_EXTERN_FLAG = 0x02;
892 : : static const uint8_t FNTYPE_IS_VARADIC_FLAG = 0X04;
893 : :
894 : 24503 : FnType (HirId ref, DefId id, std::string identifier, RustIdent ident,
895 : : uint8_t flags, ABI abi, std::vector<FnParam> params, BaseType *type,
896 : : std::vector<SubstitutionParamMapping> subst_refs,
897 : : SubstitutionArgumentMappings substitution_argument_mappings,
898 : : RegionConstraints region_constraints,
899 : : std::set<HirId> refs = std::set<HirId> ())
900 : 24503 : : CallableTypeInterface (ref, ref, TypeKind::FNDEF, ident, refs),
901 : : SubstitutionRef (std::move (subst_refs), substitution_argument_mappings,
902 : : region_constraints),
903 : 24503 : params (std::move (params)), type (type), flags (flags),
904 : 49006 : identifier (identifier), id (id), abi (abi)
905 : : {
906 : 24503 : LocalDefId local_def_id = id.localDefId;
907 : 24503 : rust_assert (local_def_id != UNKNOWN_LOCAL_DEFID);
908 : 24503 : }
909 : :
910 : 12995 : FnType (HirId ref, HirId ty_ref, DefId id, std::string identifier,
911 : : RustIdent ident, uint8_t flags, ABI abi, std::vector<FnParam> params,
912 : : BaseType *type, std::vector<SubstitutionParamMapping> subst_refs,
913 : : SubstitutionArgumentMappings substitution_argument_mappings,
914 : : RegionConstraints region_constraints,
915 : : std::set<HirId> refs = std::set<HirId> ())
916 : 12995 : : CallableTypeInterface (ref, ty_ref, TypeKind::FNDEF, ident, refs),
917 : : SubstitutionRef (std::move (subst_refs), substitution_argument_mappings,
918 : : region_constraints),
919 : 12995 : params (std::move (params)), type (type), flags (flags),
920 : 25990 : identifier (identifier), id (id), abi (abi)
921 : : {
922 : 12995 : LocalDefId local_def_id = id.localDefId;
923 : 12995 : rust_assert (local_def_id != UNKNOWN_LOCAL_DEFID);
924 : 12995 : }
925 : :
926 : : FnType (const FnType &) = delete;
927 : : FnType (FnType &&) = default;
928 : :
929 : : void accept_vis (TyVisitor &vis) override;
930 : : void accept_vis (TyConstVisitor &vis) const override;
931 : :
932 : : std::string as_string () const override;
933 : :
934 : 29687 : std::string get_name () const override final { return as_string (); }
935 : :
936 : 57742 : std::string get_identifier () const { return identifier; }
937 : :
938 : : bool can_eq (const BaseType *other, bool emit_errors) const override final;
939 : :
940 : : bool is_equal (const BaseType &other) const override;
941 : :
942 : 63212 : size_t num_params () const { return params.size (); }
943 : :
944 : 35441 : bool is_method () const
945 : : {
946 : 35441 : if (num_params () == 0)
947 : : return false;
948 : :
949 : 20361 : return (flags & FNTYPE_IS_METHOD_FLAG) != 0;
950 : : }
951 : :
952 : : bool is_extern () const { return (flags & FNTYPE_IS_EXTERN_FLAG) != 0; }
953 : :
954 : 26801 : bool is_variadic () const { return (flags & FNTYPE_IS_VARADIC_FLAG) != 0; }
955 : :
956 : 49180 : DefId get_id () const { return id; }
957 : :
958 : : // get the Self type for the method
959 : 16537 : BaseType *get_self_type () const
960 : : {
961 : 33074 : rust_assert (is_method ());
962 : 33074 : return param_at (0).get_type ();
963 : : }
964 : :
965 : 11339 : std::vector<FnParam> &get_params () { return params; }
966 : :
967 : 22642 : const std::vector<FnParam> &get_params () const { return params; }
968 : :
969 : 20290 : FnParam ¶m_at (size_t idx) { return params.at (idx); }
970 : :
971 : 27675 : const FnParam ¶m_at (size_t idx) const { return params.at (idx); }
972 : :
973 : : BaseType *clone () const final override;
974 : :
975 : : FnType *
976 : : handle_substitions (SubstitutionArgumentMappings &mappings) override final;
977 : :
978 : 32227 : ABI get_abi () const { return abi; }
979 : 0 : uint8_t get_flags () const { return flags; }
980 : :
981 : 22 : WARN_UNUSED_RESULT size_t get_num_params () const override
982 : : {
983 : 22 : return params.size ();
984 : : }
985 : :
986 : 22 : WARN_UNUSED_RESULT BaseType *get_param_type_at (size_t index) const override
987 : : {
988 : 22 : return param_at (index).get_type ();
989 : : }
990 : :
991 : 95799 : WARN_UNUSED_RESULT BaseType *get_return_type () const override
992 : : {
993 : 95799 : return type;
994 : : }
995 : :
996 : : private:
997 : : std::vector<FnParam> params;
998 : : BaseType *type;
999 : : uint8_t flags;
1000 : : std::string identifier;
1001 : : DefId id;
1002 : : ABI abi;
1003 : : };
1004 : :
1005 : : class FnPtr : public CallableTypeInterface
1006 : : {
1007 : : public:
1008 : : static constexpr auto KIND = TypeKind::FNPTR;
1009 : :
1010 : 64 : FnPtr (HirId ref, location_t locus, std::vector<TyVar> params,
1011 : : TyVar result_type, std::set<HirId> refs = std::set<HirId> ())
1012 : 64 : : CallableTypeInterface (ref, ref, TypeKind::FNPTR,
1013 : 64 : {Resolver::CanonicalPath::create_empty (), locus},
1014 : : refs),
1015 : 128 : params (std::move (params)), result_type (result_type)
1016 : 64 : {}
1017 : :
1018 : 118 : FnPtr (HirId ref, HirId ty_ref, location_t locus, std::vector<TyVar> params,
1019 : : TyVar result_type, std::set<HirId> refs = std::set<HirId> ())
1020 : 118 : : CallableTypeInterface (ref, ty_ref, TypeKind::FNPTR,
1021 : 118 : {Resolver::CanonicalPath::create_empty (), locus},
1022 : : refs),
1023 : 236 : params (params), result_type (result_type)
1024 : 118 : {}
1025 : :
1026 : 550 : std::string get_name () const override final { return as_string (); }
1027 : :
1028 : 0 : WARN_UNUSED_RESULT size_t get_num_params () const override
1029 : : {
1030 : 0 : return params.size ();
1031 : : }
1032 : :
1033 : 234 : WARN_UNUSED_RESULT BaseType *get_param_type_at (size_t index) const override
1034 : : {
1035 : 234 : return params.at (index).get_tyty ();
1036 : : }
1037 : :
1038 : 1100 : WARN_UNUSED_RESULT BaseType *get_return_type () const override
1039 : : {
1040 : 1100 : return result_type.get_tyty ();
1041 : : }
1042 : :
1043 : 0 : const TyVar &get_var_return_type () const { return result_type; }
1044 : :
1045 : 316 : size_t num_params () const { return params.size (); }
1046 : :
1047 : : void accept_vis (TyVisitor &vis) override;
1048 : : void accept_vis (TyConstVisitor &vis) const override;
1049 : :
1050 : : std::string as_string () const override;
1051 : :
1052 : : bool can_eq (const BaseType *other, bool emit_errors) const override final;
1053 : :
1054 : : bool is_equal (const BaseType &other) const override;
1055 : :
1056 : : BaseType *clone () const final override;
1057 : :
1058 : 8 : std::vector<TyVar> &get_params () { return params; }
1059 : 844 : const std::vector<TyVar> &get_params () const { return params; }
1060 : :
1061 : : private:
1062 : : std::vector<TyVar> params;
1063 : : TyVar result_type;
1064 : : };
1065 : :
1066 : : class ClosureType : public CallableTypeInterface, public SubstitutionRef
1067 : : {
1068 : : public:
1069 : : static constexpr auto KIND = TypeKind::CLOSURE;
1070 : :
1071 : 61 : ClosureType (HirId ref, DefId id, RustIdent ident, TupleType *parameters,
1072 : : TyVar result_type,
1073 : : std::vector<SubstitutionParamMapping> subst_refs,
1074 : : std::set<NodeId> captures,
1075 : : std::set<HirId> refs = std::set<HirId> (),
1076 : : std::vector<TypeBoundPredicate> specified_bounds
1077 : : = std::vector<TypeBoundPredicate> ())
1078 : 61 : : CallableTypeInterface (ref, ref, TypeKind::CLOSURE, ident, refs),
1079 : : SubstitutionRef (std::move (subst_refs),
1080 : 122 : SubstitutionArgumentMappings::error (),
1081 : : {}), // TODO: check region constraints
1082 : 61 : parameters (parameters), result_type (std::move (result_type)), id (id),
1083 : 122 : captures (captures)
1084 : : {
1085 : 61 : LocalDefId local_def_id = id.localDefId;
1086 : 61 : rust_assert (local_def_id != UNKNOWN_LOCAL_DEFID);
1087 : 61 : inherit_bounds (specified_bounds);
1088 : 61 : }
1089 : :
1090 : 420 : ClosureType (HirId ref, HirId ty_ref, RustIdent ident, DefId id,
1091 : : TupleType *parameters, TyVar result_type,
1092 : : std::vector<SubstitutionParamMapping> subst_refs,
1093 : : std::set<NodeId> captures,
1094 : : std::set<HirId> refs = std::set<HirId> (),
1095 : : std::vector<TypeBoundPredicate> specified_bounds
1096 : : = std::vector<TypeBoundPredicate> ())
1097 : 420 : : CallableTypeInterface (ref, ty_ref, TypeKind::CLOSURE, ident, refs),
1098 : : SubstitutionRef (std::move (subst_refs),
1099 : 840 : SubstitutionArgumentMappings::error (), {}), // TODO
1100 : 420 : parameters (parameters), result_type (std::move (result_type)), id (id),
1101 : 840 : captures (captures)
1102 : : {
1103 : 420 : LocalDefId local_def_id = id.localDefId;
1104 : 420 : rust_assert (local_def_id != UNKNOWN_LOCAL_DEFID);
1105 : 420 : inherit_bounds (specified_bounds);
1106 : 420 : }
1107 : :
1108 : : void accept_vis (TyVisitor &vis) override;
1109 : : void accept_vis (TyConstVisitor &vis) const override;
1110 : :
1111 : 0 : WARN_UNUSED_RESULT size_t get_num_params () const override
1112 : : {
1113 : 0 : return parameters->num_fields ();
1114 : : }
1115 : :
1116 : 0 : WARN_UNUSED_RESULT BaseType *get_param_type_at (size_t index) const override
1117 : : {
1118 : 0 : return parameters->get_field (index);
1119 : : }
1120 : :
1121 : 0 : WARN_UNUSED_RESULT BaseType *get_return_type () const override
1122 : : {
1123 : 0 : return result_type.get_tyty ();
1124 : : }
1125 : :
1126 : : std::string as_string () const override;
1127 : 1276 : std::string get_name () const override final { return as_string (); }
1128 : :
1129 : : bool can_eq (const BaseType *other, bool emit_errors) const override final;
1130 : :
1131 : : bool is_equal (const BaseType &other) const override;
1132 : :
1133 : : BaseType *clone () const final override;
1134 : :
1135 : : ClosureType *
1136 : : handle_substitions (SubstitutionArgumentMappings &mappings) override final;
1137 : :
1138 : 489 : TyTy::TupleType &get_parameters () const { return *parameters; }
1139 : 565 : TyTy::BaseType &get_result_type () const { return *result_type.get_tyty (); }
1140 : :
1141 : 376 : DefId get_def_id () const { return id; }
1142 : :
1143 : : void setup_fn_once_output () const;
1144 : :
1145 : 304 : const std::set<NodeId> &get_captures () const { return captures; }
1146 : :
1147 : : private:
1148 : : TyTy::TupleType *parameters;
1149 : : TyVar result_type;
1150 : : DefId id;
1151 : : std::set<NodeId> captures;
1152 : : };
1153 : :
1154 : 4416 : class ArrayType : public BaseType
1155 : : {
1156 : : public:
1157 : : static constexpr auto KIND = TypeKind::ARRAY;
1158 : :
1159 : 1110 : ArrayType (HirId ref, location_t locus, HIR::Expr &capacity_expr, TyVar base,
1160 : : std::set<HirId> refs = std::set<HirId> ())
1161 : 1110 : : BaseType (ref, ref, TypeKind::ARRAY,
1162 : 1110 : {Resolver::CanonicalPath::create_empty (), locus}, refs),
1163 : 2220 : element_type (base), capacity_expr (capacity_expr)
1164 : 1110 : {}
1165 : :
1166 : 2856 : ArrayType (HirId ref, HirId ty_ref, location_t locus,
1167 : : HIR::Expr &capacity_expr, TyVar base,
1168 : : std::set<HirId> refs = std::set<HirId> ())
1169 : 2856 : : BaseType (ref, ty_ref, TypeKind::ARRAY,
1170 : 2856 : {Resolver::CanonicalPath::create_empty (), locus}, refs),
1171 : 5712 : element_type (base), capacity_expr (capacity_expr)
1172 : 2856 : {}
1173 : :
1174 : : void accept_vis (TyVisitor &vis) override;
1175 : : void accept_vis (TyConstVisitor &vis) const override;
1176 : :
1177 : : std::string as_string () const override;
1178 : :
1179 : 15250 : std::string get_name () const override final { return as_string (); }
1180 : :
1181 : : bool can_eq (const BaseType *other, bool emit_errors) const override final;
1182 : :
1183 : : bool is_equal (const BaseType &other) const override;
1184 : :
1185 : : BaseType *get_element_type () const;
1186 : : const TyVar &get_var_element_type () const;
1187 : :
1188 : : BaseType *clone () const final override;
1189 : :
1190 : 5449 : HIR::Expr &get_capacity_expr () const { return capacity_expr; }
1191 : :
1192 : : ArrayType *handle_substitions (SubstitutionArgumentMappings &mappings);
1193 : :
1194 : : private:
1195 : : TyVar element_type;
1196 : : // FIXME: I dont think this should be in tyty - tyty should already be const
1197 : : // evaluated
1198 : : HIR::Expr &capacity_expr;
1199 : : };
1200 : :
1201 : 6114 : class SliceType : public BaseType
1202 : : {
1203 : : public:
1204 : : static constexpr auto KIND = TypeKind::SLICE;
1205 : :
1206 : 869 : SliceType (HirId ref, location_t locus, TyVar base,
1207 : : std::set<HirId> refs = std::set<HirId> ())
1208 : 869 : : BaseType (ref, ref, TypeKind::SLICE,
1209 : 869 : {Resolver::CanonicalPath::create_empty (), locus}, refs),
1210 : 1738 : element_type (base)
1211 : 869 : {}
1212 : :
1213 : 45106 : SliceType (HirId ref, HirId ty_ref, location_t locus, TyVar base,
1214 : : std::set<HirId> refs = std::set<HirId> ())
1215 : 45106 : : BaseType (ref, ty_ref, TypeKind::SLICE,
1216 : 45106 : {Resolver::CanonicalPath::create_empty (), locus}, refs),
1217 : 90212 : element_type (base)
1218 : 45106 : {}
1219 : :
1220 : : void accept_vis (TyVisitor &vis) override;
1221 : : void accept_vis (TyConstVisitor &vis) const override;
1222 : :
1223 : : std::string as_string () const override;
1224 : :
1225 : 21525 : std::string get_name () const override final { return as_string (); }
1226 : :
1227 : : bool can_eq (const BaseType *other, bool emit_errors) const override final;
1228 : :
1229 : : bool is_equal (const BaseType &other) const override;
1230 : :
1231 : : BaseType *get_element_type () const;
1232 : : const TyVar &get_var_element_type () const;
1233 : :
1234 : : BaseType *clone () const final override;
1235 : :
1236 : : SliceType *handle_substitions (SubstitutionArgumentMappings &mappings);
1237 : :
1238 : : private:
1239 : : TyVar element_type;
1240 : : };
1241 : :
1242 : : class BoolType : public BaseType
1243 : : {
1244 : : public:
1245 : : static constexpr auto KIND = TypeKind::BOOL;
1246 : :
1247 : : BoolType (HirId ref, std::set<HirId> refs = std::set<HirId> ());
1248 : : BoolType (HirId ref, HirId ty_ref, std::set<HirId> refs = std::set<HirId> ());
1249 : :
1250 : : void accept_vis (TyVisitor &vis) override;
1251 : : void accept_vis (TyConstVisitor &vis) const override;
1252 : :
1253 : : std::string as_string () const override;
1254 : :
1255 : : std::string get_name () const override final;
1256 : :
1257 : : bool can_eq (const BaseType *other, bool emit_errors) const override final;
1258 : :
1259 : : BaseType *clone () const final override;
1260 : : };
1261 : :
1262 : : class IntType : public BaseType
1263 : : {
1264 : : public:
1265 : : enum IntKind
1266 : : {
1267 : : I8,
1268 : : I16,
1269 : : I32,
1270 : : I64,
1271 : : I128
1272 : : };
1273 : :
1274 : : static constexpr auto KIND = TypeKind::INT;
1275 : :
1276 : : IntType (HirId ref, IntKind kind, std::set<HirId> refs = std::set<HirId> ());
1277 : : IntType (HirId ref, HirId ty_ref, IntKind kind,
1278 : : std::set<HirId> refs = std::set<HirId> ());
1279 : :
1280 : : void accept_vis (TyVisitor &vis) override;
1281 : : void accept_vis (TyConstVisitor &vis) const override;
1282 : :
1283 : : std::string as_string () const override;
1284 : :
1285 : : std::string get_name () const override final;
1286 : :
1287 : : bool can_eq (const BaseType *other, bool emit_errors) const override final;
1288 : :
1289 : : IntKind get_int_kind () const;
1290 : :
1291 : : BaseType *clone () const final override;
1292 : :
1293 : : bool is_equal (const BaseType &other) const override;
1294 : :
1295 : : private:
1296 : : IntKind int_kind;
1297 : : };
1298 : :
1299 : : class UintType : public BaseType
1300 : : {
1301 : : public:
1302 : : static constexpr auto KIND = TypeKind::UINT;
1303 : :
1304 : : enum UintKind
1305 : : {
1306 : : U8,
1307 : : U16,
1308 : : U32,
1309 : : U64,
1310 : : U128
1311 : : };
1312 : :
1313 : : UintType (HirId ref, UintKind kind,
1314 : : std::set<HirId> refs = std::set<HirId> ());
1315 : : UintType (HirId ref, HirId ty_ref, UintKind kind,
1316 : : std::set<HirId> refs = std::set<HirId> ());
1317 : :
1318 : : void accept_vis (TyVisitor &vis) override;
1319 : : void accept_vis (TyConstVisitor &vis) const override;
1320 : :
1321 : : std::string as_string () const override;
1322 : :
1323 : : std::string get_name () const override final;
1324 : :
1325 : : bool can_eq (const BaseType *other, bool emit_errors) const override final;
1326 : :
1327 : : UintKind get_uint_kind () const;
1328 : :
1329 : : BaseType *clone () const final override;
1330 : :
1331 : : bool is_equal (const BaseType &other) const override;
1332 : :
1333 : : private:
1334 : : UintKind uint_kind;
1335 : : };
1336 : :
1337 : : class FloatType : public BaseType
1338 : : {
1339 : : public:
1340 : : static constexpr auto KIND = TypeKind::FLOAT;
1341 : :
1342 : : enum FloatKind
1343 : : {
1344 : : F32,
1345 : : F64
1346 : : };
1347 : :
1348 : : FloatType (HirId ref, FloatKind kind,
1349 : : std::set<HirId> refs = std::set<HirId> ());
1350 : : FloatType (HirId ref, HirId ty_ref, FloatKind kind,
1351 : : std::set<HirId> refs = std::set<HirId> ());
1352 : :
1353 : : void accept_vis (TyVisitor &vis) override;
1354 : : void accept_vis (TyConstVisitor &vis) const override;
1355 : :
1356 : : std::string as_string () const override;
1357 : : std::string get_name () const override final;
1358 : :
1359 : : bool can_eq (const BaseType *other, bool emit_errors) const override final;
1360 : :
1361 : : FloatKind get_float_kind () const;
1362 : :
1363 : : BaseType *clone () const final override;
1364 : :
1365 : : bool is_equal (const BaseType &other) const override;
1366 : :
1367 : : private:
1368 : : FloatKind float_kind;
1369 : : };
1370 : :
1371 : : class USizeType : public BaseType
1372 : : {
1373 : : public:
1374 : : static constexpr auto KIND = TypeKind::USIZE;
1375 : :
1376 : : USizeType (HirId ref, std::set<HirId> refs = std::set<HirId> ());
1377 : : USizeType (HirId ref, HirId ty_ref,
1378 : : std::set<HirId> refs = std::set<HirId> ());
1379 : :
1380 : : void accept_vis (TyVisitor &vis) override;
1381 : : void accept_vis (TyConstVisitor &vis) const override;
1382 : :
1383 : : std::string as_string () const override;
1384 : : std::string get_name () const override final;
1385 : :
1386 : : bool can_eq (const BaseType *other, bool emit_errors) const override final;
1387 : :
1388 : : BaseType *clone () const final override;
1389 : : };
1390 : :
1391 : : class ISizeType : public BaseType
1392 : : {
1393 : : public:
1394 : : static constexpr auto KIND = TypeKind::ISIZE;
1395 : :
1396 : : ISizeType (HirId ref, std::set<HirId> refs = std::set<HirId> ());
1397 : : ISizeType (HirId ref, HirId ty_ref,
1398 : : std::set<HirId> refs = std::set<HirId> ());
1399 : :
1400 : : void accept_vis (TyVisitor &vis) override;
1401 : : void accept_vis (TyConstVisitor &vis) const override;
1402 : :
1403 : : std::string as_string () const override;
1404 : : std::string get_name () const override final;
1405 : :
1406 : : bool can_eq (const BaseType *other, bool emit_errors) const override final;
1407 : :
1408 : : BaseType *clone () const final override;
1409 : : };
1410 : :
1411 : : class CharType : public BaseType
1412 : : {
1413 : : public:
1414 : : static constexpr auto KIND = TypeKind::CHAR;
1415 : :
1416 : : CharType (HirId ref, std::set<HirId> refs = std::set<HirId> ());
1417 : : CharType (HirId ref, HirId ty_ref, std::set<HirId> refs = std::set<HirId> ());
1418 : :
1419 : : void accept_vis (TyVisitor &vis) override;
1420 : : void accept_vis (TyConstVisitor &vis) const override;
1421 : :
1422 : : std::string as_string () const override;
1423 : : std::string get_name () const override final;
1424 : :
1425 : : bool can_eq (const BaseType *other, bool emit_errors) const override final;
1426 : :
1427 : : BaseType *clone () const final override;
1428 : : };
1429 : :
1430 : : class StrType : public BaseType
1431 : : {
1432 : : public:
1433 : : static constexpr auto KIND = TypeKind::STR;
1434 : :
1435 : : StrType (HirId ref, std::set<HirId> refs = std::set<HirId> ());
1436 : : StrType (HirId ref, HirId ty_ref, std::set<HirId> refs = std::set<HirId> ());
1437 : :
1438 : : std::string get_name () const override final;
1439 : :
1440 : : void accept_vis (TyVisitor &vis) override;
1441 : : void accept_vis (TyConstVisitor &vis) const override;
1442 : :
1443 : : std::string as_string () const override;
1444 : :
1445 : : bool can_eq (const BaseType *other, bool emit_errors) const override final;
1446 : :
1447 : : bool is_equal (const BaseType &other) const override;
1448 : :
1449 : : BaseType *clone () const final override;
1450 : : };
1451 : :
1452 : : class DynamicObjectType : public BaseType
1453 : : {
1454 : : public:
1455 : : static constexpr auto KIND = TypeKind::DYNAMIC;
1456 : :
1457 : : DynamicObjectType (HirId ref, RustIdent ident,
1458 : : std::vector<TypeBoundPredicate> specified_bounds,
1459 : : std::set<HirId> refs = std::set<HirId> ());
1460 : :
1461 : : DynamicObjectType (HirId ref, HirId ty_ref, RustIdent ident,
1462 : : std::vector<TypeBoundPredicate> specified_bounds,
1463 : : std::set<HirId> refs = std::set<HirId> ());
1464 : :
1465 : : void accept_vis (TyVisitor &vis) override;
1466 : : void accept_vis (TyConstVisitor &vis) const override;
1467 : :
1468 : : std::string as_string () const override;
1469 : :
1470 : : bool can_eq (const BaseType *other, bool emit_errors) const override final;
1471 : :
1472 : : bool is_equal (const BaseType &other) const override;
1473 : :
1474 : : BaseType *clone () const final override;
1475 : :
1476 : : std::string get_name () const override final;
1477 : :
1478 : : // this returns a flat list of items including super trait bounds
1479 : : const std::vector<
1480 : : std::pair<const Resolver::TraitItemReference *, const TypeBoundPredicate *>>
1481 : : get_object_items () const;
1482 : : };
1483 : :
1484 : 13522 : class ReferenceType : public BaseType
1485 : : {
1486 : : public:
1487 : : static constexpr auto KIND = REF;
1488 : :
1489 : : ReferenceType (HirId ref, TyVar base, Mutability mut,
1490 : : Region region = Region::make_anonymous (),
1491 : : std::set<HirId> refs = std::set<HirId> ());
1492 : : ReferenceType (HirId ref, HirId ty_ref, TyVar base, Mutability mut,
1493 : : Region region = Region::make_anonymous (),
1494 : : std::set<HirId> refs = std::set<HirId> ());
1495 : :
1496 : : BaseType *get_base () const;
1497 : : const TyVar &get_var_element_type () const;
1498 : :
1499 : : void accept_vis (TyVisitor &vis) override;
1500 : : void accept_vis (TyConstVisitor &vis) const override;
1501 : :
1502 : : std::string as_string () const override;
1503 : :
1504 : : std::string get_name () const override final;
1505 : :
1506 : : bool can_eq (const BaseType *other, bool emit_errors) const override final;
1507 : :
1508 : : bool is_equal (const BaseType &other) const override;
1509 : :
1510 : : BaseType *clone () const final override;
1511 : :
1512 : : ReferenceType *handle_substitions (SubstitutionArgumentMappings &mappings);
1513 : :
1514 : : Mutability mutability () const;
1515 : : bool is_mutable () const;
1516 : :
1517 : : WARN_UNUSED_RESULT Region get_region () const;
1518 : : void set_region (Region region);
1519 : :
1520 : : bool is_dyn_object () const;
1521 : : bool is_dyn_slice_type (const TyTy::SliceType **slice = nullptr) const;
1522 : : bool is_dyn_str_type (const TyTy::StrType **str = nullptr) const;
1523 : : bool is_dyn_obj_type (const TyTy::DynamicObjectType **dyn = nullptr) const;
1524 : :
1525 : : private:
1526 : : TyVar base;
1527 : : Mutability mut;
1528 : : Region region;
1529 : : };
1530 : :
1531 : 31998 : class PointerType : public BaseType
1532 : : {
1533 : : public:
1534 : : static constexpr auto KIND = TypeKind::POINTER;
1535 : :
1536 : : PointerType (HirId ref, TyVar base, Mutability mut,
1537 : : std::set<HirId> refs = std::set<HirId> ());
1538 : : PointerType (HirId ref, HirId ty_ref, TyVar base, Mutability mut,
1539 : : std::set<HirId> refs = std::set<HirId> ());
1540 : :
1541 : : BaseType *get_base () const;
1542 : : const TyVar &get_var_element_type () const;
1543 : :
1544 : : void accept_vis (TyVisitor &vis) override;
1545 : : void accept_vis (TyConstVisitor &vis) const override;
1546 : :
1547 : : std::string as_string () const override;
1548 : : std::string get_name () const override final;
1549 : :
1550 : : bool can_eq (const BaseType *other, bool emit_errors) const override final;
1551 : :
1552 : : bool is_equal (const BaseType &other) const override;
1553 : :
1554 : : BaseType *clone () const final override;
1555 : :
1556 : : PointerType *handle_substitions (SubstitutionArgumentMappings &mappings);
1557 : :
1558 : : Mutability mutability () const;
1559 : : bool is_mutable () const;
1560 : : bool is_const () const;
1561 : : bool is_dyn_object () const;
1562 : : bool is_dyn_slice_type (const TyTy::SliceType **slice = nullptr) const;
1563 : : bool is_dyn_str_type (const TyTy::StrType **str = nullptr) const;
1564 : : bool is_dyn_obj_type (const TyTy::DynamicObjectType **dyn = nullptr) const;
1565 : :
1566 : : private:
1567 : : TyVar base;
1568 : : Mutability mut;
1569 : : };
1570 : :
1571 : : // https://doc.rust-lang.org/std/primitive.never.html
1572 : : //
1573 : : // Since the `!` type is really complicated and it is even still unstable
1574 : : // in rustc, only fairly limited support for this type is introduced here.
1575 : : // Unification between `!` and ANY other type (including `<T?>`) is simply
1576 : : // not allowed. If it is needed, it should be handled manually. For example,
1577 : : // unifying `!` with other types is very necessary when resolving types of
1578 : : // `if/else` expressions.
1579 : : //
1580 : : // See related discussion at https://github.com/Rust-GCC/gccrs/pull/364
1581 : : class NeverType : public BaseType
1582 : : {
1583 : : public:
1584 : : static constexpr auto KIND = TypeKind::NEVER;
1585 : :
1586 : : NeverType (HirId ref, std::set<HirId> refs = std::set<HirId> ());
1587 : :
1588 : : NeverType (HirId ref, HirId ty_ref,
1589 : : std::set<HirId> refs = std::set<HirId> ());
1590 : :
1591 : : void accept_vis (TyVisitor &vis) override;
1592 : :
1593 : : void accept_vis (TyConstVisitor &vis) const override;
1594 : :
1595 : : std::string as_string () const override;
1596 : :
1597 : : bool can_eq (const BaseType *other, bool emit_errors) const override final;
1598 : :
1599 : : BaseType *clone () const final override;
1600 : :
1601 : : std::string get_name () const override final;
1602 : : };
1603 : :
1604 : : // used at the type in associated types in traits
1605 : : // see: https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
1606 : : class PlaceholderType : public BaseType
1607 : : {
1608 : : public:
1609 : : static constexpr auto KIND = TypeKind::PLACEHOLDER;
1610 : :
1611 : : PlaceholderType (std::string symbol, DefId id, HirId ref,
1612 : : std::set<HirId> refs = std::set<HirId> ());
1613 : : PlaceholderType (std::string symbol, DefId id, HirId ref, HirId ty_ref,
1614 : : std::set<HirId> refs = std::set<HirId> ());
1615 : :
1616 : : void accept_vis (TyVisitor &vis) override;
1617 : : void accept_vis (TyConstVisitor &vis) const override;
1618 : :
1619 : : std::string as_string () const override;
1620 : :
1621 : : bool can_eq (const BaseType *other, bool emit_errors) const override final;
1622 : :
1623 : : BaseType *clone () const final override;
1624 : :
1625 : : std::string get_name () const override final;
1626 : :
1627 : : std::string get_symbol () const;
1628 : :
1629 : : void set_associated_type (HirId ref);
1630 : :
1631 : : void clear_associated_type ();
1632 : :
1633 : : bool can_resolve () const;
1634 : :
1635 : : BaseType *resolve () const;
1636 : :
1637 : : bool is_equal (const BaseType &other) const override;
1638 : :
1639 : : DefId get_def_id () const;
1640 : :
1641 : : private:
1642 : : std::string symbol;
1643 : : DefId defId;
1644 : : };
1645 : :
1646 : : class ProjectionType : public BaseType, public SubstitutionRef
1647 : : {
1648 : : public:
1649 : : static constexpr auto KIND = TypeKind::PROJECTION;
1650 : :
1651 : : ProjectionType (HirId ref, BaseType *base,
1652 : : const Resolver::TraitReference *trait, DefId item,
1653 : : std::vector<SubstitutionParamMapping> subst_refs,
1654 : : SubstitutionArgumentMappings generic_arguments
1655 : : = SubstitutionArgumentMappings::error (),
1656 : : RegionConstraints region_constraints = {},
1657 : : std::set<HirId> refs = std::set<HirId> ());
1658 : :
1659 : : ProjectionType (HirId ref, HirId ty_ref, BaseType *base,
1660 : : const Resolver::TraitReference *trait, DefId item,
1661 : : std::vector<SubstitutionParamMapping> subst_refs,
1662 : : SubstitutionArgumentMappings generic_arguments
1663 : : = SubstitutionArgumentMappings::error (),
1664 : : RegionConstraints region_constraints = {},
1665 : : std::set<HirId> refs = std::set<HirId> ());
1666 : :
1667 : : void accept_vis (TyVisitor &vis) override;
1668 : : void accept_vis (TyConstVisitor &vis) const override;
1669 : :
1670 : : std::string as_string () const override;
1671 : :
1672 : : bool can_eq (const BaseType *other, bool emit_errors) const override final;
1673 : :
1674 : : BaseType *clone () const final override;
1675 : :
1676 : : std::string get_name () const override final;
1677 : :
1678 : : const BaseType *get () const;
1679 : : BaseType *get ();
1680 : :
1681 : : ProjectionType *
1682 : : handle_substitions (SubstitutionArgumentMappings &mappings) override final;
1683 : :
1684 : : private:
1685 : : BaseType *base;
1686 : : const Resolver::TraitReference *trait;
1687 : : DefId item;
1688 : : };
1689 : :
1690 : : template <>
1691 : : WARN_UNUSED_RESULT inline bool
1692 : 22 : BaseType::is<CallableTypeInterface> () const
1693 : : {
1694 : 22 : auto kind = this->get_kind ();
1695 : 22 : return kind == FNPTR || kind == FNDEF || kind == CLOSURE;
1696 : : }
1697 : :
1698 : : template <>
1699 : : WARN_UNUSED_RESULT inline bool
1700 : 11 : BaseType::is<const CallableTypeInterface> () const
1701 : : {
1702 : 11 : return this->is<CallableTypeInterface> ();
1703 : : }
1704 : :
1705 : : template <>
1706 : : WARN_UNUSED_RESULT inline bool
1707 : 17 : BaseType::is<SubstitutionRef> () const
1708 : : {
1709 : 17 : auto kind = this->get_kind ();
1710 : 34 : return kind == FNPTR || kind == FNDEF || kind == CLOSURE || kind == ADT
1711 : 17 : || kind == PROJECTION;
1712 : : }
1713 : :
1714 : : template <>
1715 : : WARN_UNUSED_RESULT inline bool
1716 : : BaseType::is<const SubstitutionRef> () const
1717 : : {
1718 : : return this->is<SubstitutionRef> ();
1719 : : }
1720 : :
1721 : : template <>
1722 : : WARN_UNUSED_RESULT inline SubstitutionRef *
1723 : 16 : BaseType::as<SubstitutionRef> ()
1724 : : {
1725 : 16 : auto kind = this->get_kind ();
1726 : 16 : switch (kind)
1727 : : {
1728 : 0 : case FNDEF:
1729 : 0 : return static_cast<FnType *> (this);
1730 : 0 : case CLOSURE:
1731 : 0 : return static_cast<ClosureType *> (this);
1732 : 16 : case ADT:
1733 : 16 : return static_cast<ADTType *> (this);
1734 : 0 : case PROJECTION:
1735 : 0 : return static_cast<ProjectionType *> (this);
1736 : 0 : default:
1737 : 0 : rust_unreachable ();
1738 : : }
1739 : : }
1740 : :
1741 : : template <>
1742 : : WARN_UNUSED_RESULT inline const SubstitutionRef *
1743 : 5 : BaseType::as<const SubstitutionRef> () const
1744 : : {
1745 : 5 : auto kind = this->get_kind ();
1746 : 5 : switch (kind)
1747 : : {
1748 : 0 : case FNDEF:
1749 : 0 : return static_cast<const FnType *> (this);
1750 : 0 : case CLOSURE:
1751 : 0 : return static_cast<const ClosureType *> (this);
1752 : 5 : case ADT:
1753 : 5 : return static_cast<const ADTType *> (this);
1754 : 0 : case PROJECTION:
1755 : 0 : return static_cast<const ProjectionType *> (this);
1756 : 0 : default:
1757 : 0 : rust_unreachable ();
1758 : : }
1759 : : }
1760 : :
1761 : : template <>
1762 : : WARN_UNUSED_RESULT inline SubstitutionRef *
1763 : 17 : BaseType::try_as<SubstitutionRef> ()
1764 : : {
1765 : 17 : if (this->is<SubstitutionRef> ())
1766 : : {
1767 : 16 : return this->as<SubstitutionRef> ();
1768 : : }
1769 : : return nullptr;
1770 : : }
1771 : :
1772 : : template <>
1773 : : WARN_UNUSED_RESULT inline const SubstitutionRef *
1774 : : BaseType::try_as<const SubstitutionRef> () const
1775 : : {
1776 : : if (this->is<const SubstitutionRef> ())
1777 : : {
1778 : : return this->as<const SubstitutionRef> ();
1779 : : }
1780 : : return nullptr;
1781 : : }
1782 : :
1783 : : } // namespace TyTy
1784 : : } // namespace Rust
1785 : :
1786 : : #endif // RUST_TYTY
|