diff options
author | Philip Herron <philip.herron@embecosm.com> | 2021-07-20 13:47:56 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2021-07-20 18:46:04 +0100 |
commit | aa4feb8867da90a03d1d04dcfa61a049a2779df5 (patch) | |
tree | b108c383397dc0bf36153c6eabdebe62d42a20e6 /gcc | |
parent | 02713d245aaffd45d8daaf8c914b1dda5baa6eb4 (diff) | |
download | gcc-aa4feb8867da90a03d1d04dcfa61a049a2779df5.zip gcc-aa4feb8867da90a03d1d04dcfa61a049a2779df5.tar.gz gcc-aa4feb8867da90a03d1d04dcfa61a049a2779df5.tar.bz2 |
Raw pointer support
This adds the initial support for raw pointers. Pointers rely on coercion
rules to be able to coerce the raw fat pointers from a borrow expression
into a normal raw pointer.
Fixes #124
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/backend/rust-compile-context.h | 25 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-tyty.h | 2 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-type.h | 21 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-full-test.cc | 19 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-type.h | 38 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-type.h | 5 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-const-fold.h | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-type.h | 9 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-substitution-mapper.h | 8 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-call.h | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-cmp.h | 54 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-coercion.h | 92 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-rules.h | 60 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-visitor.h | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.cc | 79 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.h | 51 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/torture/coercion2.rs | 20 |
17 files changed, 448 insertions, 41 deletions
diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h index efca267..bb4f0ab 100644 --- a/gcc/rust/backend/rust-compile-context.h +++ b/gcc/rust/backend/rust-compile-context.h @@ -536,10 +536,29 @@ public: { Btype *base_compiled_type = TyTyResolveCompile::compile (ctx, type.get_base ()); - translated = ctx->get_backend ()->reference_type (base_compiled_type); - if (!type.is_mutable ()) + if (type.is_mutable ()) { - translated = ctx->get_backend ()->immutable_type (translated); + translated = ctx->get_backend ()->reference_type (base_compiled_type); + } + else + { + auto base = ctx->get_backend ()->immutable_type (base_compiled_type); + translated = ctx->get_backend ()->reference_type (base); + } + } + + void visit (TyTy::PointerType &type) override + { + Btype *base_compiled_type + = TyTyResolveCompile::compile (ctx, type.get_base ()); + if (type.is_mutable ()) + { + translated = ctx->get_backend ()->pointer_type (base_compiled_type); + } + else + { + auto base = ctx->get_backend ()->immutable_type (base_compiled_type); + translated = ctx->get_backend ()->pointer_type (base); } } diff --git a/gcc/rust/backend/rust-compile-tyty.h b/gcc/rust/backend/rust-compile-tyty.h index d2890e0..2d0856d 100644 --- a/gcc/rust/backend/rust-compile-tyty.h +++ b/gcc/rust/backend/rust-compile-tyty.h @@ -62,6 +62,8 @@ public: void visit (TyTy::ReferenceType &) override { gcc_unreachable (); } + void visit (TyTy::PointerType &) override { gcc_unreachable (); } + void visit (TyTy::ParamType &) override { gcc_unreachable (); } void visit (TyTy::FnPtr &) override { gcc_unreachable (); } diff --git a/gcc/rust/hir/rust-ast-lower-type.h b/gcc/rust/hir/rust-ast-lower-type.h index 0b534d0..efaf9db 100644 --- a/gcc/rust/hir/rust-ast-lower-type.h +++ b/gcc/rust/hir/rust-ast-lower-type.h @@ -229,6 +229,27 @@ public: translated); } + void visit (AST::RawPointerType &type) override + { + HIR::Type *base_type + = ASTLoweringType::translate (type.get_type_pointed_to ().get ()); + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, type.get_node_id (), + mappings->get_next_hir_id (crate_num), + mappings->get_next_localdef_id (crate_num)); + + translated + = new HIR::RawPointerType (mapping, + type.get_pointer_type () + == AST::RawPointerType::PointerType::MUT, + std::unique_ptr<HIR::Type> (base_type), + type.get_locus ()); + + mappings->insert_hir_type (mapping.get_crate_num (), mapping.get_hirid (), + translated); + } + void visit (AST::InferredType &type) override { auto crate_num = mappings->get_current_crate (); diff --git a/gcc/rust/hir/tree/rust-hir-full-test.cc b/gcc/rust/hir/tree/rust-hir-full-test.cc index 05c75e0..86664d3 100644 --- a/gcc/rust/hir/tree/rust-hir-full-test.cc +++ b/gcc/rust/hir/tree/rust-hir-full-test.cc @@ -2806,23 +2806,8 @@ ReferenceType::as_string () const std::string RawPointerType::as_string () const { - std::string str ("*"); - - switch (pointer_type) - { - case MUT: - str += "mut "; - break; - case CONST: - str += "const "; - break; - default: - return "ERROR_MARK_STRING - unknown pointer type in raw pointer type"; - } - - str += type->as_string (); - - return str; + return std::string ("*") + (is_mut () ? "mut " : "const ") + + type->as_string (); } std::string diff --git a/gcc/rust/hir/tree/rust-hir-type.h b/gcc/rust/hir/tree/rust-hir-type.h index c4771b6..3cb4be1 100644 --- a/gcc/rust/hir/tree/rust-hir-type.h +++ b/gcc/rust/hir/tree/rust-hir-type.h @@ -446,41 +446,31 @@ public: // A type consisting of a pointer without safety or liveness guarantees class RawPointerType : public TypeNoBounds { -public: - enum PointerType - { - MUT, - CONST - }; - private: - PointerType pointer_type; - std::unique_ptr<TypeNoBounds> type; + bool is_mutable; + std::unique_ptr<Type> type; Location locus; public: - // Returns whether the pointer is mutable or constant. - PointerType get_pointer_type () const { return pointer_type; } - // Constructor requires pointer for polymorphism reasons - RawPointerType (Analysis::NodeMapping mappings, PointerType pointer_type, - std::unique_ptr<TypeNoBounds> type_no_bounds, Location locus) - : TypeNoBounds (mappings), pointer_type (pointer_type), - type (std::move (type_no_bounds)), locus (locus) + RawPointerType (Analysis::NodeMapping mappings, bool is_mutable, + std::unique_ptr<Type> type, Location locus) + : TypeNoBounds (mappings), is_mutable (is_mutable), type (std::move (type)), + locus (locus) {} // Copy constructor calls custom polymorphic clone function RawPointerType (RawPointerType const &other) - : TypeNoBounds (other.mappings), pointer_type (other.pointer_type), - type (other.type->clone_type_no_bounds ()), locus (other.locus) + : TypeNoBounds (other.mappings), is_mutable (other.is_mutable), + type (other.type->clone_type ()), locus (other.locus) {} // overload assignment operator to use custom clone method RawPointerType &operator= (RawPointerType const &other) { mappings = other.mappings; - pointer_type = other.pointer_type; - type = other.type->clone_type_no_bounds (); + is_mutable = other.is_mutable; + type = other.type->clone_type (); locus = other.locus; return *this; } @@ -495,6 +485,14 @@ public: void accept_vis (HIRVisitor &vis) override; + std::unique_ptr<Type> &get_type () { return type; } + + bool is_mut () const { return is_mutable; } + + bool is_const () const { return !is_mutable; } + + std::unique_ptr<Type> &get_base_type () { return type; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h index 23419b0..d826d68 100644 --- a/gcc/rust/resolve/rust-ast-resolve-type.h +++ b/gcc/rust/resolve/rust-ast-resolve-type.h @@ -281,6 +281,11 @@ public: void visit (AST::InferredType &type) override { ok = true; } + void visit (AST::RawPointerType &type) override + { + type.get_type_pointed_to ()->accept_vis (*this); + } + private: ResolveType (NodeId parent, bool canonicalize_type_with_generics) : ResolverBase (parent), diff --git a/gcc/rust/typecheck/rust-hir-const-fold.h b/gcc/rust/typecheck/rust-hir-const-fold.h index c71dd39..f6c6616 100644 --- a/gcc/rust/typecheck/rust-hir-const-fold.h +++ b/gcc/rust/typecheck/rust-hir-const-fold.h @@ -45,6 +45,8 @@ public: void visit (TyTy::ReferenceType &) override { gcc_unreachable (); } + void visit (TyTy::PointerType &) override { gcc_unreachable (); } + void visit (TyTy::ParamType &) override { gcc_unreachable (); } void visit (TyTy::FnPtr &) override { gcc_unreachable (); } diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.h b/gcc/rust/typecheck/rust-hir-type-check-type.h index 567d482..0f75c54 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-type.h +++ b/gcc/rust/typecheck/rust-hir-type-check-type.h @@ -194,6 +194,15 @@ public: type.get_has_mut ()); } + void visit (HIR::RawPointerType &type) override + { + TyTy::BaseType *base + = TypeCheckType::Resolve (type.get_base_type ().get ()); + translated + = new TyTy::PointerType (type.get_mappings ().get_hirid (), + TyTy::TyVar (base->get_ref ()), type.is_mut ()); + } + void visit (HIR::InferredType &type) override { translated = new TyTy::InferType (type.get_mappings ().get_hirid (), diff --git a/gcc/rust/typecheck/rust-substitution-mapper.h b/gcc/rust/typecheck/rust-substitution-mapper.h index 9741dfa..3730faa 100644 --- a/gcc/rust/typecheck/rust-substitution-mapper.h +++ b/gcc/rust/typecheck/rust-substitution-mapper.h @@ -103,6 +103,7 @@ public: void visit (TyTy::ErrorType &) override { gcc_unreachable (); } void visit (TyTy::CharType &) override { gcc_unreachable (); } void visit (TyTy::ReferenceType &) override { gcc_unreachable (); } + void visit (TyTy::PointerType &) override { gcc_unreachable (); } void visit (TyTy::ParamType &) override { gcc_unreachable (); } void visit (TyTy::StrType &) override { gcc_unreachable (); } void visit (TyTy::NeverType &) override { gcc_unreachable (); } @@ -165,6 +166,11 @@ public: resolved = type.handle_substitions (mappings); } + void visit (TyTy::PointerType &type) override + { + resolved = type.handle_substitions (mappings); + } + void visit (TyTy::ParamType &type) override { resolved = type.handle_substitions (mappings); @@ -237,6 +243,7 @@ public: void visit (TyTy::ErrorType &) override { gcc_unreachable (); } void visit (TyTy::CharType &) override { gcc_unreachable (); } void visit (TyTy::ReferenceType &) override { gcc_unreachable (); } + void visit (TyTy::PointerType &) override { gcc_unreachable (); } void visit (TyTy::ParamType &) override { gcc_unreachable (); } void visit (TyTy::StrType &) override { gcc_unreachable (); } void visit (TyTy::NeverType &) override { gcc_unreachable (); } @@ -286,6 +293,7 @@ public: void visit (TyTy::ErrorType &) override { gcc_unreachable (); } void visit (TyTy::CharType &) override { gcc_unreachable (); } void visit (TyTy::ReferenceType &) override { gcc_unreachable (); } + void visit (TyTy::PointerType &) override { gcc_unreachable (); } void visit (TyTy::ParamType &) override { gcc_unreachable (); } void visit (TyTy::StrType &) override { gcc_unreachable (); } void visit (TyTy::NeverType &) override { gcc_unreachable (); } diff --git a/gcc/rust/typecheck/rust-tyty-call.h b/gcc/rust/typecheck/rust-tyty-call.h index f6121ca..636d40b 100644 --- a/gcc/rust/typecheck/rust-tyty-call.h +++ b/gcc/rust/typecheck/rust-tyty-call.h @@ -51,6 +51,7 @@ public: void visit (ErrorType &type) override { gcc_unreachable (); } void visit (CharType &type) override { gcc_unreachable (); } void visit (ReferenceType &type) override { gcc_unreachable (); } + void visit (PointerType &type) override { gcc_unreachable (); } void visit (ParamType &) override { gcc_unreachable (); } void visit (StrType &) override { gcc_unreachable (); } void visit (NeverType &) override { gcc_unreachable (); } @@ -100,6 +101,7 @@ public: void visit (ADTType &type) override { gcc_unreachable (); }; void visit (CharType &type) override { gcc_unreachable (); } void visit (ReferenceType &type) override { gcc_unreachable (); } + void visit (PointerType &type) override { gcc_unreachable (); } void visit (ParamType &) override { gcc_unreachable (); } void visit (StrType &) override { gcc_unreachable (); } void visit (NeverType &) override { gcc_unreachable (); } diff --git a/gcc/rust/typecheck/rust-tyty-cmp.h b/gcc/rust/typecheck/rust-tyty-cmp.h index e856c41..049a4b7 100644 --- a/gcc/rust/typecheck/rust-tyty-cmp.h +++ b/gcc/rust/typecheck/rust-tyty-cmp.h @@ -289,6 +289,22 @@ public: } } + virtual void visit (const PointerType &type) override + { + ok = false; + if (emit_error_flag) + { + Location ref_locus = mappings->lookup_location (type.get_ref ()); + Location base_locus + = mappings->lookup_location (get_base ()->get_ref ()); + RichLocation r (ref_locus); + r.add_range (base_locus); + rust_error_at (r, "expected [%s] got [%s]", + get_base ()->as_string ().c_str (), + type.as_string ().c_str ()); + } + } + virtual void visit (const StrType &type) override { ok = false; @@ -542,7 +558,19 @@ public: } void visit (const ReferenceType &type) override + { + bool is_valid + = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL); + if (is_valid) + { + ok = true; + return; + } + + BaseCmp::visit (type); + } + void visit (const PointerType &type) override { bool is_valid = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL); @@ -997,7 +1025,8 @@ public: auto base_type = base->get_base (); auto other_base_type = type.get_base (); - ok = base_type->can_eq (other_base_type, emit_error_flag); + ok = base_type->can_eq (other_base_type, emit_error_flag) + && (base->is_mutable () == type.is_mutable ()); } private: @@ -1005,6 +1034,29 @@ private: const ReferenceType *base; }; +class PointerCmp : public BaseCmp +{ + using Rust::TyTy::BaseCmp::visit; + +public: + PointerCmp (const PointerType *base, bool emit_errors) + : BaseCmp (base, emit_errors), base (base) + {} + + void visit (const ReferenceType &type) override + { + auto base_type = base->get_base (); + auto other_base_type = type.get_base (); + + ok = base_type->can_eq (other_base_type, emit_error_flag) + && (base->is_mutable () == type.is_mutable ()); + } + +private: + const BaseType *get_base () const override { return base; } + const PointerType *base; +}; + class ParamCmp : public BaseCmp { using Rust::TyTy::BaseCmp::visit; diff --git a/gcc/rust/typecheck/rust-tyty-coercion.h b/gcc/rust/typecheck/rust-tyty-coercion.h index 5c10b04..f19871e 100644 --- a/gcc/rust/typecheck/rust-tyty-coercion.h +++ b/gcc/rust/typecheck/rust-tyty-coercion.h @@ -252,6 +252,17 @@ public: type.as_string ().c_str ()); } + virtual void visit (PointerType &type) override + { + Location ref_locus = mappings->lookup_location (type.get_ref ()); + Location base_locus = mappings->lookup_location (get_base ()->get_ref ()); + RichLocation r (ref_locus); + r.add_range (base_locus); + rust_error_at (r, "expected [%s] got [%s]", + get_base ()->as_string ().c_str (), + type.as_string ().c_str ()); + } + virtual void visit (ParamType &type) override { Location ref_locus = mappings->lookup_location (type.get_ref ()); @@ -507,7 +518,19 @@ public: } void visit (ReferenceType &type) override + { + bool is_valid + = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL); + if (is_valid) + { + resolved = type.clone (); + return; + } + BaseCoercionRules::visit (type); + } + + void visit (PointerType &type) override { bool is_valid = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL); @@ -1087,6 +1110,75 @@ private: ReferenceType *base; }; +class PointerCoercionRules : public BaseCoercionRules +{ + using Rust::TyTy::BaseCoercionRules::visit; + +public: + PointerCoercionRules (PointerType *base) + : BaseCoercionRules (base), base (base) + {} + + void visit (ReferenceType &type) override + { + auto base_type = base->get_base (); + auto other_base_type = type.get_base (); + + TyTy::BaseType *base_resolved = base_type->unify (other_base_type); + if (base_resolved == nullptr + || base_resolved->get_kind () == TypeKind::ERROR) + { + BaseCoercionRules::visit (type); + return; + } + + // we can allow for mutability changes here by casting down from mutability + // eg: mut vs const, we cant take a mutable pointer from a const + // eg: const vs mut we can take a const reference from a mutable one + if (!base->is_mutable () || (base->is_mutable () == type.is_mutable ())) + { + resolved = new PointerType (base->get_ref (), base->get_ty_ref (), + TyVar (base_resolved->get_ref ()), + base->is_mutable ()); + return; + } + + BaseCoercionRules::visit (type); + } + + void visit (PointerType &type) override + { + auto base_type = base->get_base (); + auto other_base_type = type.get_base (); + + TyTy::BaseType *base_resolved = base_type->unify (other_base_type); + if (base_resolved == nullptr + || base_resolved->get_kind () == TypeKind::ERROR) + { + BaseCoercionRules::visit (type); + return; + } + + // we can allow for mutability changes here by casting down from mutability + // eg: mut vs const, we cant take a mutable pointer from a const one + // eg: const vs mut we can take a const reference from a mutable one + if (!base->is_mutable () || (base->is_mutable () == type.is_mutable ())) + { + resolved = new PointerType (base->get_ref (), base->get_ty_ref (), + TyVar (base_resolved->get_ref ()), + base->is_mutable ()); + return; + } + + BaseCoercionRules::visit (type); + } + +private: + BaseType *get_base () override { return base; } + + PointerType *base; +}; + class ParamCoercionRules : public BaseCoercionRules { using Rust::TyTy::BaseCoercionRules::visit; diff --git a/gcc/rust/typecheck/rust-tyty-rules.h b/gcc/rust/typecheck/rust-tyty-rules.h index 31d7191..de9a5d9 100644 --- a/gcc/rust/typecheck/rust-tyty-rules.h +++ b/gcc/rust/typecheck/rust-tyty-rules.h @@ -274,6 +274,17 @@ public: type.as_string ().c_str ()); } + virtual void visit (PointerType &type) override + { + Location ref_locus = mappings->lookup_location (type.get_ref ()); + Location base_locus = mappings->lookup_location (get_base ()->get_ref ()); + RichLocation r (ref_locus); + r.add_range (base_locus); + rust_error_at (r, "expected [%s] got [%s]", + get_base ()->as_string ().c_str (), + type.as_string ().c_str ()); + } + virtual void visit (ParamType &type) override { Location ref_locus = mappings->lookup_location (type.get_ref ()); @@ -528,7 +539,19 @@ public: } void visit (ReferenceType &type) override + { + bool is_valid + = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL); + if (is_valid) + { + resolved = type.clone (); + return; + } + BaseRules::visit (type); + } + + void visit (PointerType &type) override { bool is_valid = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL); @@ -1098,6 +1121,43 @@ private: ReferenceType *base; }; +class PointerRules : public BaseRules +{ + using Rust::TyTy::BaseRules::visit; + +public: + PointerRules (PointerType *base) : BaseRules (base), base (base) {} + + void visit (PointerType &type) override + { + auto base_type = base->get_base (); + auto other_base_type = type.get_base (); + + TyTy::BaseType *base_resolved = base_type->unify (other_base_type); + if (base_resolved == nullptr + || base_resolved->get_kind () == TypeKind::ERROR) + { + BaseRules::visit (type); + return; + } + + if (base->is_mutable () != type.is_mutable ()) + { + BaseRules::visit (type); + return; + } + + resolved = new PointerType (base->get_ref (), base->get_ty_ref (), + TyVar (base_resolved->get_ref ()), + base->is_mutable ()); + } + +private: + BaseType *get_base () override { return base; } + + PointerType *base; +}; + class ParamRules : public BaseRules { using Rust::TyTy::BaseRules::visit; diff --git a/gcc/rust/typecheck/rust-tyty-visitor.h b/gcc/rust/typecheck/rust-tyty-visitor.h index 2dd97b8..66b11b9 100644 --- a/gcc/rust/typecheck/rust-tyty-visitor.h +++ b/gcc/rust/typecheck/rust-tyty-visitor.h @@ -42,6 +42,7 @@ public: virtual void visit (ErrorType &type) = 0; virtual void visit (CharType &type) = 0; virtual void visit (ReferenceType &type) = 0; + virtual void visit (PointerType &type) = 0; virtual void visit (ParamType &type) = 0; virtual void visit (StrType &type) = 0; virtual void visit (NeverType &type) = 0; @@ -66,6 +67,7 @@ public: virtual void visit (const ErrorType &type) = 0; virtual void visit (const CharType &type) = 0; virtual void visit (const ReferenceType &type) = 0; + virtual void visit (const PointerType &type) = 0; virtual void visit (const ParamType &type) = 0; virtual void visit (const StrType &type) = 0; virtual void visit (const NeverType &type) = 0; diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc index 16bb01b..f043c7e 100644 --- a/gcc/rust/typecheck/rust-tyty.cc +++ b/gcc/rust/typecheck/rust-tyty.cc @@ -1518,6 +1518,85 @@ ReferenceType::handle_substitions (SubstitutionArgumentMappings mappings) } void +PointerType::accept_vis (TyVisitor &vis) +{ + vis.visit (*this); +} + +void +PointerType::accept_vis (TyConstVisitor &vis) const +{ + vis.visit (*this); +} + +std::string +PointerType::as_string () const +{ + return std::string ("* ") + (is_mutable () ? "mut" : "const") + " " + + get_base ()->as_string (); +} + +BaseType * +PointerType::unify (BaseType *other) +{ + PointerRules r (this); + return r.unify (other); +} + +BaseType * +PointerType::coerce (BaseType *other) +{ + PointerCoercionRules r (this); + return r.coerce (other); +} + +bool +PointerType::can_eq (const BaseType *other, bool emit_errors) const +{ + PointerCmp r (this, emit_errors); + return r.can_eq (other); +} + +bool +PointerType::is_equal (const BaseType &other) const +{ + if (get_kind () != other.get_kind ()) + return false; + + auto other2 = static_cast<const PointerType &> (other); + return get_base ()->is_equal (*other2.get_base ()); +} + +BaseType * +PointerType::get_base () const +{ + return base.get_tyty (); +} + +BaseType * +PointerType::clone () +{ + return new PointerType (get_ref (), get_ty_ref (), base, is_mutable (), + get_combined_refs ()); +} + +PointerType * +PointerType::handle_substitions (SubstitutionArgumentMappings mappings) +{ + auto mappings_table = Analysis::Mappings::get (); + + PointerType *ref = static_cast<PointerType *> (clone ()); + ref->set_ty_ref (mappings_table->get_next_hir_id ()); + + // might be &T or &ADT so this needs to be recursive + auto base = ref->get_base (); + BaseType *concrete = Resolver::SubstMapperInternal::Resolve (base, mappings); + ref->base = TyVar (concrete->get_ty_ref ()); + + return ref; +} + +void ParamType::accept_vis (TyVisitor &vis) { vis.visit (*this); diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h index c0af9f6..2152c1b 100644 --- a/gcc/rust/typecheck/rust-tyty.h +++ b/gcc/rust/typecheck/rust-tyty.h @@ -35,6 +35,7 @@ enum TypeKind ADT, STR, REF, + POINTER, PARAM, ARRAY, FNDEF, @@ -72,6 +73,9 @@ public: case TypeKind::REF: return "REF"; + case TypeKind::POINTER: + return "POINTER"; + case TypeKind::PARAM: return "PARAM"; @@ -1432,6 +1436,53 @@ private: bool is_mut; }; +class PointerType : public BaseType +{ +public: + PointerType (HirId ref, TyVar base, bool is_mut, + std::set<HirId> refs = std::set<HirId> ()) + : BaseType (ref, ref, TypeKind::POINTER, refs), base (base), is_mut (is_mut) + {} + + PointerType (HirId ref, HirId ty_ref, TyVar base, bool is_mut, + std::set<HirId> refs = std::set<HirId> ()) + : BaseType (ref, ty_ref, TypeKind::POINTER, refs), base (base), + is_mut (is_mut) + {} + + BaseType *get_base () const; + + void accept_vis (TyVisitor &vis) override; + void accept_vis (TyConstVisitor &vis) const override; + + std::string as_string () const override; + + std::string get_name () const override final { return as_string (); } + + BaseType *unify (BaseType *other) override; + bool can_eq (const BaseType *other, bool emit_errors) const override final; + BaseType *coerce (BaseType *other) override; + + bool is_equal (const BaseType &other) const override; + + BaseType *clone () final override; + + bool contains_type_parameters () const override final + { + return get_base ()->contains_type_parameters (); + } + + PointerType *handle_substitions (SubstitutionArgumentMappings mappings); + + bool is_mutable () const { return is_mut; } + + bool is_const () const { return !is_mut; } + +private: + TyVar base; + bool is_mut; +}; + class StrType : public BaseType { public: diff --git a/gcc/testsuite/rust/compile/torture/coercion2.rs b/gcc/testsuite/rust/compile/torture/coercion2.rs new file mode 100644 index 0000000..127f257 --- /dev/null +++ b/gcc/testsuite/rust/compile/torture/coercion2.rs @@ -0,0 +1,20 @@ +pub fn main() { + let a: *const i32 = &123; + // { dg-warning "unused name" "" { target *-*-* } .-1 } + let b: &i32 = &123; + // { dg-warning "unused name" "" { target *-*-* } .-1 } + + let c: &mut i32 = &mut 123; + // { dg-warning "unused name" "" { target *-*-* } .-1 } + let d: *mut i32 = &mut 123; + // { dg-warning "unused name" "" { target *-*-* } .-1 } + + let e: &i32 = &mut 123; + // { dg-warning "unused name" "" { target *-*-* } .-1 } + let f: *const i32 = &mut 123; + // { dg-warning "unused name" "" { target *-*-* } .-1 } + + let g = &123; + let h: *const i32 = g; + // { dg-warning "unused name" "" { target *-*-* } .-1 } +} |