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