diff options
author | Philip Herron <philip.herron@embecosm.com> | 2021-10-20 19:39:01 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2021-10-22 11:48:42 +0100 |
commit | 243e5d800dc03f36025e72d275b79a2098dbb953 (patch) | |
tree | de1905c8fe94727095d0aead8c883dc1b4b76016 /gcc | |
parent | fe77d2d5747b0c9f44c01eba4f6898fbb2790f23 (diff) | |
download | gcc-243e5d800dc03f36025e72d275b79a2098dbb953.zip gcc-243e5d800dc03f36025e72d275b79a2098dbb953.tar.gz gcc-243e5d800dc03f36025e72d275b79a2098dbb953.tar.bz2 |
Ensure autoderef for generic recivers in method calls
This changes our TyTy::BaseType::can_eq interface to allow
ParamTypes to be compatable with everything except reference
and pointer types to ensure we apply autoderef adjustments
correctly.
Fixes #753
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/typecheck/rust-hir-dot-operator.h | 6 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-inherent-impl-overlap.h | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-path-probe.h | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-expr.h | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-implitem.h | 6 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-path.cc | 7 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check.h | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-bounds.cc | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-cmp.h | 227 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.cc | 115 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.h | 72 | ||||
-rw-r--r-- | gcc/testsuite/rust/execute/torture/trait8.rs | 41 |
12 files changed, 323 insertions, 161 deletions
diff --git a/gcc/rust/typecheck/rust-hir-dot-operator.h b/gcc/rust/typecheck/rust-hir-dot-operator.h index 9c0cc43..98ae5ab 100644 --- a/gcc/rust/typecheck/rust-hir-dot-operator.h +++ b/gcc/rust/typecheck/rust-hir-dot-operator.h @@ -115,7 +115,7 @@ private: if (fn->is_method ()) { TyTy::BaseType *fn_self = fn->get_self_type (); - if (receiver->can_eq (fn_self, false)) + if (receiver->can_eq (fn_self, false, true)) { return &c; } @@ -143,7 +143,7 @@ private: if (fn->is_method ()) { TyTy::BaseType *fn_self = fn->get_self_type (); - if (receiver->can_eq (fn_self, false)) + if (receiver->can_eq (fn_self, false, true)) { return &c; } @@ -165,7 +165,7 @@ private: if (fn->is_method ()) { TyTy::BaseType *fn_self = fn->get_self_type (); - if (receiver->can_eq (fn_self, false)) + if (receiver->can_eq (fn_self, false, true)) { return &c; } diff --git a/gcc/rust/typecheck/rust-hir-inherent-impl-overlap.h b/gcc/rust/typecheck/rust-hir-inherent-impl-overlap.h index 9a2c7fe..eac86b0 100644 --- a/gcc/rust/typecheck/rust-hir-inherent-impl-overlap.h +++ b/gcc/rust/typecheck/rust-hir-inherent-impl-overlap.h @@ -122,7 +122,7 @@ public: if (query == candidate) continue; - if (query->can_eq (candidate, false)) + if (query->can_eq (candidate, false, false)) possible_collision (it->second, iy->second); } } diff --git a/gcc/rust/typecheck/rust-hir-path-probe.h b/gcc/rust/typecheck/rust-hir-path-probe.h index d2b5f5b..8ceec00 100644 --- a/gcc/rust/typecheck/rust-hir-path-probe.h +++ b/gcc/rust/typecheck/rust-hir-path-probe.h @@ -227,7 +227,7 @@ protected: bool ok = context->lookup_type (impl_ty_id, &impl_block_ty); rust_assert (ok); - if (!receiver->can_eq (impl_block_ty, false)) + if (!receiver->can_eq (impl_block_ty, false, false)) return; // lets visit the impl_item diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h index 83fafa6..8c415ebd 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.h +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h @@ -320,7 +320,7 @@ public: // always be at the end of the list auto s = fn->get_self_type ()->get_root (); - rust_assert (s->can_eq (adt, false)); + rust_assert (s->can_eq (adt, false, false)); rust_assert (s->get_kind () == TyTy::TypeKind::ADT); const TyTy::ADTType *self_adt = static_cast<const TyTy::ADTType *> (s); diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.h b/gcc/rust/typecheck/rust-hir-type-check-implitem.h index 1260c2e..f3a0870 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-implitem.h +++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.h @@ -377,7 +377,7 @@ public: return; // check the types are compatible - if (!resolved_trait_item.get_tyty ()->can_eq (lookup, true)) + if (!resolved_trait_item.get_tyty ()->can_eq (lookup, true, false)) { RichLocation r (constant.get_locus ()); r.add_range (resolved_trait_item.get_locus ()); @@ -413,7 +413,7 @@ public: return; // check the types are compatible - if (!resolved_trait_item.get_tyty ()->can_eq (lookup, true)) + if (!resolved_trait_item.get_tyty ()->can_eq (lookup, true, false)) { RichLocation r (type.get_locus ()); r.add_range (resolved_trait_item.get_locus ()); @@ -487,7 +487,7 @@ public: = trait_item_fntype->handle_substitions (implicit_self_substs); // check the types are compatible - if (!trait_item_fntype->can_eq (fntype, true)) + if (!trait_item_fntype->can_eq (fntype, true, false)) { RichLocation r (function.get_locus ()); r.add_range (resolved_trait_item.get_locus ()); diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc b/gcc/rust/typecheck/rust-hir-type-check-path.cc index 0aea8ca..c74ac85 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-path.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc @@ -376,9 +376,12 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id, AssociatedImplTrait *lookup_associated = nullptr; bool found_impl_trait = context->lookup_associated_trait_impl ( impl->get_mappings ().get_hirid (), &lookup_associated); - rust_assert (found_impl_trait); - lookup_associated->setup_associated_types (); + // setup associated mappings if possible we might be resolving a + // path within a default implementation of a trait function + // see: testsuite/rust/compile/torture/traits16.rs + if (found_impl_trait) + lookup_associated->setup_associated_types (); // we need a new ty_ref_id for this trait item tyseg = tyseg->clone (); diff --git a/gcc/rust/typecheck/rust-hir-type-check.h b/gcc/rust/typecheck/rust-hir-type-check.h index d3dc4c9..5760c4e 100644 --- a/gcc/rust/typecheck/rust-hir-type-check.h +++ b/gcc/rust/typecheck/rust-hir-type-check.h @@ -187,7 +187,7 @@ public: for (auto &item : it->second) { - if (item.first->can_eq (self, false)) + if (item.first->can_eq (self, false, false)) { *mapping = item.second; return true; diff --git a/gcc/rust/typecheck/rust-tyty-bounds.cc b/gcc/rust/typecheck/rust-tyty-bounds.cc index 5f69deb..8909394 100644 --- a/gcc/rust/typecheck/rust-tyty-bounds.cc +++ b/gcc/rust/typecheck/rust-tyty-bounds.cc @@ -40,7 +40,7 @@ TypeBoundsProbe::scan () if (!ok) return true; - if (!receiver->can_eq (impl_type, false)) + if (!receiver->can_eq (impl_type, false, false)) return true; possible_trait_paths.push_back ({impl->get_trait_ref ().get (), impl}); diff --git a/gcc/rust/typecheck/rust-tyty-cmp.h b/gcc/rust/typecheck/rust-tyty-cmp.h index 519501f..9ebd564 100644 --- a/gcc/rust/typecheck/rust-tyty-cmp.h +++ b/gcc/rust/typecheck/rust-tyty-cmp.h @@ -371,8 +371,18 @@ public: virtual void visit (const ParamType &type) override { - // it is ok for types to can eq to a ParamType - ok = true; + 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 DynamicObjectType &type) override @@ -408,10 +418,10 @@ public: } protected: - BaseCmp (const BaseType *base, bool emit_errors) + BaseCmp (const BaseType *base, bool emit_errors, bool autoderef_mode) : mappings (Analysis::Mappings::get ()), context (Resolver::TypeCheckContext::get ()), ok (false), - emit_error_flag (emit_errors) + emit_error_flag (emit_errors), autoderef_mode_flag (autoderef_mode) {} Analysis::Mappings *mappings; @@ -419,6 +429,7 @@ protected: bool ok; bool emit_error_flag; + bool autoderef_mode_flag; private: /* Returns a pointer to the ty that created this rule. */ @@ -430,8 +441,8 @@ class InferCmp : public BaseCmp using Rust::TyTy::BaseCmp::visit; public: - InferCmp (const InferType *base, bool emit_errors) - : BaseCmp (base, emit_errors), base (base) + InferCmp (const InferType *base, bool emit_errors, bool autoderef_mode) + : BaseCmp (base, emit_errors, autoderef_mode), base (base) {} void visit (const BoolType &type) override @@ -641,18 +652,7 @@ public: BaseCmp::visit (type); } - void visit (const ParamType &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 ParamType &) override { ok = true; } void visit (const DynamicObjectType &type) override { @@ -690,8 +690,8 @@ class FnCmp : public BaseCmp using Rust::TyTy::BaseCmp::visit; public: - FnCmp (const FnType *base, bool emit_errors) - : BaseCmp (base, emit_errors), base (base) + FnCmp (const FnType *base, bool emit_errors, bool autoderef_mode) + : BaseCmp (base, emit_errors, autoderef_mode), base (base) {} void visit (const InferType &type) override @@ -712,7 +712,7 @@ public: auto a = base->param_at (i).second; auto b = type.param_at (i).second; - if (!a->can_eq (b, emit_error_flag)) + if (!a->can_eq (b, emit_error_flag, autoderef_mode_flag)) { emit_error_flag = false; BaseCmp::visit (type); @@ -721,7 +721,8 @@ public: } if (!base->get_return_type ()->can_eq (type.get_return_type (), - emit_error_flag)) + emit_error_flag, + autoderef_mode_flag)) { emit_error_flag = false; BaseCmp::visit (type); @@ -741,8 +742,8 @@ class FnptrCmp : public BaseCmp using Rust::TyTy::BaseCmp::visit; public: - FnptrCmp (const FnPtr *base, bool emit_errors) - : BaseCmp (base, emit_errors), base (base) + FnptrCmp (const FnPtr *base, bool emit_errors, bool autoderef_mode) + : BaseCmp (base, emit_errors, autoderef_mode), base (base) {} void visit (const InferType &type) override @@ -766,7 +767,8 @@ public: auto this_ret_type = base->get_return_type (); auto other_ret_type = type.get_return_type (); - if (!this_ret_type->can_eq (other_ret_type, emit_error_flag)) + if (!this_ret_type->can_eq (other_ret_type, emit_error_flag, + autoderef_mode_flag)) { BaseCmp::visit (type); return; @@ -776,7 +778,8 @@ public: { auto this_param = base->param_at (i); auto other_param = type.param_at (i); - if (!this_param->can_eq (other_param, emit_error_flag)) + if (!this_param->can_eq (other_param, emit_error_flag, + autoderef_mode_flag)) { BaseCmp::visit (type); return; @@ -796,7 +799,8 @@ public: auto this_ret_type = base->get_return_type (); auto other_ret_type = type.get_return_type (); - if (!this_ret_type->can_eq (other_ret_type, emit_error_flag)) + if (!this_ret_type->can_eq (other_ret_type, emit_error_flag, + autoderef_mode_flag)) { BaseCmp::visit (type); return; @@ -806,7 +810,8 @@ public: { auto this_param = base->param_at (i); auto other_param = type.param_at (i).second; - if (!this_param->can_eq (other_param, emit_error_flag)) + if (!this_param->can_eq (other_param, emit_error_flag, + autoderef_mode_flag)) { BaseCmp::visit (type); return; @@ -826,8 +831,8 @@ class ClosureCmp : public BaseCmp using Rust::TyTy::BaseCmp::visit; public: - ClosureCmp (const ClosureType *base, bool emit_errors) - : BaseCmp (base, emit_errors), base (base) + ClosureCmp (const ClosureType *base, bool emit_errors, bool autoderef_mode) + : BaseCmp (base, emit_errors, autoderef_mode), base (base) {} private: @@ -840,8 +845,8 @@ class ArrayCmp : public BaseCmp using Rust::TyTy::BaseCmp::visit; public: - ArrayCmp (const ArrayType *base, bool emit_errors) - : BaseCmp (base, emit_errors), base (base) + ArrayCmp (const ArrayType *base, bool emit_errors, bool autoderef_mode) + : BaseCmp (base, emit_errors, autoderef_mode), base (base) {} void visit (const ArrayType &type) override @@ -856,7 +861,8 @@ public: // check base type const BaseType *base_element = base->get_element_type (); const BaseType *other_element = type.get_element_type (); - if (!base_element->can_eq (other_element, emit_error_flag)) + if (!base_element->can_eq (other_element, emit_error_flag, + autoderef_mode_flag)) { BaseCmp::visit (type); return; @@ -865,6 +871,8 @@ public: ok = true; } + void visit (const ParamType &type) override { ok = true; } + private: const BaseType *get_base () const override { return base; } const ArrayType *base; @@ -875,8 +883,8 @@ class BoolCmp : public BaseCmp using Rust::TyTy::BaseCmp::visit; public: - BoolCmp (const BoolType *base, bool emit_errors) - : BaseCmp (base, emit_errors), base (base) + BoolCmp (const BoolType *base, bool emit_errors, bool autoderef_mode) + : BaseCmp (base, emit_errors, autoderef_mode), base (base) {} void visit (const BoolType &type) override { ok = true; } @@ -886,6 +894,8 @@ public: ok = type.get_infer_kind () == InferType::InferTypeKind::GENERAL; } + void visit (const ParamType &type) override { ok = true; } + private: const BaseType *get_base () const override { return base; } const BoolType *base; @@ -896,8 +906,8 @@ class IntCmp : public BaseCmp using Rust::TyTy::BaseCmp::visit; public: - IntCmp (const IntType *base, bool emit_errors) - : BaseCmp (base, emit_errors), base (base) + IntCmp (const IntType *base, bool emit_errors, bool autoderef_mode) + : BaseCmp (base, emit_errors, autoderef_mode), base (base) {} void visit (const InferType &type) override @@ -910,6 +920,8 @@ public: ok = type.get_int_kind () == base->get_int_kind (); } + void visit (const ParamType &type) override { ok = true; } + private: const BaseType *get_base () const override { return base; } const IntType *base; @@ -920,8 +932,8 @@ class UintCmp : public BaseCmp using Rust::TyTy::BaseCmp::visit; public: - UintCmp (const UintType *base, bool emit_errors) - : BaseCmp (base, emit_errors), base (base) + UintCmp (const UintType *base, bool emit_errors, bool autoderef_mode) + : BaseCmp (base, emit_errors, autoderef_mode), base (base) {} void visit (const InferType &type) override @@ -934,6 +946,8 @@ public: ok = type.get_uint_kind () == base->get_uint_kind (); } + void visit (const ParamType &type) override { ok = true; } + private: const BaseType *get_base () const override { return base; } const UintType *base; @@ -944,8 +958,8 @@ class FloatCmp : public BaseCmp using Rust::TyTy::BaseCmp::visit; public: - FloatCmp (const FloatType *base, bool emit_errors) - : BaseCmp (base, emit_errors), base (base) + FloatCmp (const FloatType *base, bool emit_errors, bool autoderef_mode) + : BaseCmp (base, emit_errors, autoderef_mode), base (base) {} void visit (const InferType &type) override @@ -958,6 +972,8 @@ public: ok = type.get_float_kind () == base->get_float_kind (); } + void visit (const ParamType &type) override { ok = true; } + private: const BaseType *get_base () const override { return base; } const FloatType *base; @@ -968,8 +984,8 @@ class ADTCmp : public BaseCmp using Rust::TyTy::BaseCmp::visit; public: - ADTCmp (const ADTType *base, bool emit_errors) - : BaseCmp (base, emit_errors), base (base) + ADTCmp (const ADTType *base, bool emit_errors, bool autoderef_mode) + : BaseCmp (base, emit_errors, autoderef_mode), base (base) {} void visit (const ADTType &type) override @@ -994,7 +1010,8 @@ public: TyTy::BaseType *this_field_ty = base_field->get_field_type (); TyTy::BaseType *other_field_ty = other_field->get_field_type (); - if (!this_field_ty->can_eq (other_field_ty, emit_error_flag)) + if (!this_field_ty->can_eq (other_field_ty, emit_error_flag, + autoderef_mode_flag)) { BaseCmp::visit (type); return; @@ -1004,6 +1021,8 @@ public: ok = true; } + void visit (const ParamType &type) override { ok = true; } + private: const BaseType *get_base () const override { return base; } const ADTType *base; @@ -1014,8 +1033,8 @@ class TupleCmp : public BaseCmp using Rust::TyTy::BaseCmp::visit; public: - TupleCmp (const TupleType *base, bool emit_errors) - : BaseCmp (base, emit_errors), base (base) + TupleCmp (const TupleType *base, bool emit_errors, bool autoderef_mode) + : BaseCmp (base, emit_errors, autoderef_mode), base (base) {} void visit (const TupleType &type) override @@ -1031,7 +1050,7 @@ public: BaseType *bo = base->get_field (i); BaseType *fo = type.get_field (i); - if (!bo->can_eq (fo, emit_error_flag)) + if (!bo->can_eq (fo, emit_error_flag, autoderef_mode_flag)) { BaseCmp::visit (type); return; @@ -1041,6 +1060,8 @@ public: ok = true; } + void visit (const ParamType &type) override { ok = true; } + private: const BaseType *get_base () const override { return base; } const TupleType *base; @@ -1051,8 +1072,8 @@ class USizeCmp : public BaseCmp using Rust::TyTy::BaseCmp::visit; public: - USizeCmp (const USizeType *base, bool emit_errors) - : BaseCmp (base, emit_errors), base (base) + USizeCmp (const USizeType *base, bool emit_errors, bool autoderef_mode) + : BaseCmp (base, emit_errors, autoderef_mode), base (base) {} void visit (const InferType &type) override @@ -1062,6 +1083,8 @@ public: void visit (const USizeType &type) override { ok = true; } + void visit (const ParamType &type) override { ok = true; } + private: const BaseType *get_base () const override { return base; } const USizeType *base; @@ -1072,8 +1095,8 @@ class ISizeCmp : public BaseCmp using Rust::TyTy::BaseCmp::visit; public: - ISizeCmp (const ISizeType *base, bool emit_errors) - : BaseCmp (base, emit_errors), base (base) + ISizeCmp (const ISizeType *base, bool emit_errors, bool autoderef_mode) + : BaseCmp (base, emit_errors, autoderef_mode), base (base) {} void visit (const InferType &type) override @@ -1083,6 +1106,8 @@ public: void visit (const ISizeType &type) override { ok = true; } + void visit (const ParamType &type) override { ok = true; } + private: const BaseType *get_base () const override { return base; } const ISizeType *base; @@ -1093,8 +1118,8 @@ class CharCmp : public BaseCmp using Rust::TyTy::BaseCmp::visit; public: - CharCmp (const CharType *base, bool emit_errors) - : BaseCmp (base, emit_errors), base (base) + CharCmp (const CharType *base, bool emit_errors, bool autoderef_mode) + : BaseCmp (base, emit_errors, autoderef_mode), base (base) {} void visit (const InferType &type) override @@ -1104,6 +1129,8 @@ public: void visit (const CharType &type) override { ok = true; } + void visit (const ParamType &type) override { ok = true; } + private: const BaseType *get_base () const override { return base; } const CharType *base; @@ -1114,8 +1141,9 @@ class ReferenceCmp : public BaseCmp using Rust::TyTy::BaseCmp::visit; public: - ReferenceCmp (const ReferenceType *base, bool emit_errors) - : BaseCmp (base, emit_errors), base (base) + ReferenceCmp (const ReferenceType *base, bool emit_errors, + bool autoderef_mode) + : BaseCmp (base, emit_errors, autoderef_mode), base (base) {} void visit (const ReferenceType &type) override @@ -1123,7 +1151,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, + autoderef_mode_flag) && (base->is_mutable () == type.is_mutable ()); } @@ -1137,8 +1166,8 @@ class PointerCmp : public BaseCmp using Rust::TyTy::BaseCmp::visit; public: - PointerCmp (const PointerType *base, bool emit_errors) - : BaseCmp (base, emit_errors), base (base) + PointerCmp (const PointerType *base, bool emit_errors, bool autoderef_mode) + : BaseCmp (base, emit_errors, autoderef_mode), base (base) {} void visit (const ReferenceType &type) override @@ -1146,7 +1175,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, + autoderef_mode_flag) && (base->is_mutable () == type.is_mutable ()); } @@ -1160,8 +1190,8 @@ class ParamCmp : public BaseCmp using Rust::TyTy::BaseCmp::visit; public: - ParamCmp (const ParamType *base, bool emit_errors) - : BaseCmp (base, emit_errors), base (base) + ParamCmp (const ParamType *base, bool emit_errors, bool autoderef_mode) + : BaseCmp (base, emit_errors, autoderef_mode), base (base) {} // param types are a placeholder we shouldn't have cases where we unify @@ -1183,13 +1213,7 @@ public: bool ok = context->lookup_type (base->get_ty_ref (), &lookup); rust_assert (ok); - if (lookup->get_kind () == TypeKind::PARAM) - { - InferType infer (UNKNOWN_HIRID, InferType::InferTypeKind::GENERAL); - return infer.can_eq (other, emit_error_flag); - } - - return lookup->can_eq (other, emit_error_flag); + return lookup->can_eq (other, emit_error_flag, autoderef_mode_flag); } // imagine the case where we have: @@ -1198,7 +1222,46 @@ public: // impl <X>Foo<X> { ... } // both of these types are compatible so we mostly care about the number of // generic arguments - void visit (const ParamType &type) override { ok = true; } + void visit (const ParamType &) override { ok = true; } + + void visit (const TupleType &) override { ok = true; } + + void visit (const ADTType &) override { ok = true; } + + void visit (const InferType &) override { ok = true; } + + void visit (const FnType &) override { ok = true; } + + void visit (const FnPtr &) override { ok = true; } + + void visit (const ArrayType &) override { ok = true; } + + void visit (const BoolType &) override { ok = true; } + + void visit (const IntType &) override { ok = true; } + + void visit (const UintType &) override { ok = true; } + + void visit (const USizeType &) override { ok = true; } + + void visit (const ISizeType &) override { ok = true; } + + void visit (const FloatType &) override { ok = true; } + + void visit (const CharType &) override { ok = true; } + + void visit (const ReferenceType &) override { ok = !autoderef_mode_flag; } + + void visit (const PointerType &) override { ok = !autoderef_mode_flag; } + + void visit (const StrType &) override { ok = true; } + + void visit (const NeverType &) override { ok = true; } + + void visit (const PlaceholderType &type) override + { + ok = base->get_symbol ().compare (type.get_symbol ()) == 0; + } private: const BaseType *get_base () const override { return base; } @@ -1211,12 +1274,14 @@ class StrCmp : public BaseCmp using Rust::TyTy::BaseCmp::visit; public: - StrCmp (const StrType *base, bool emit_errors) - : BaseCmp (base, emit_errors), base (base) + StrCmp (const StrType *base, bool emit_errors, bool autoderef_mode) + : BaseCmp (base, emit_errors, autoderef_mode), base (base) {} void visit (const StrType &type) override { ok = true; } + void visit (const ParamType &type) override { ok = true; } + private: const BaseType *get_base () const override { return base; } const StrType *base; @@ -1227,12 +1292,14 @@ class NeverCmp : public BaseCmp using Rust::TyTy::BaseCmp::visit; public: - NeverCmp (const NeverType *base, bool emit_errors) - : BaseCmp (base, emit_errors), base (base) + NeverCmp (const NeverType *base, bool emit_errors, bool autoderef_mode) + : BaseCmp (base, emit_errors, autoderef_mode), base (base) {} void visit (const NeverType &type) override { ok = true; } + void visit (const ParamType &type) override { ok = true; } + private: const BaseType *get_base () const override { return base; } const NeverType *base; @@ -1243,8 +1310,9 @@ class PlaceholderCmp : public BaseCmp using Rust::TyTy::BaseCmp::visit; public: - PlaceholderCmp (const PlaceholderType *base, bool emit_errors) - : BaseCmp (base, emit_errors), base (base) + PlaceholderCmp (const PlaceholderType *base, bool emit_errors, + bool autoderef_mode) + : BaseCmp (base, emit_errors, autoderef_mode), base (base) {} bool can_eq (const BaseType *other) override @@ -1253,7 +1321,7 @@ public: return BaseCmp::can_eq (other); BaseType *lookup = base->resolve (); - return lookup->can_eq (other, emit_error_flag); + return lookup->can_eq (other, emit_error_flag, autoderef_mode_flag); } void visit (const TupleType &) override { ok = true; } @@ -1308,8 +1376,9 @@ class DynamicCmp : public BaseCmp using Rust::TyTy::BaseCmp::visit; public: - DynamicCmp (const DynamicObjectType *base, bool emit_errors) - : BaseCmp (base, emit_errors), base (base) + DynamicCmp (const DynamicObjectType *base, bool emit_errors, + bool autoderef_mode) + : BaseCmp (base, emit_errors, autoderef_mode), base (base) {} void visit (const DynamicObjectType &type) override @@ -1324,6 +1393,8 @@ public: ok = base->bounds_compatible (type, ref_locus, false); } + void visit (const ParamType &type) override { ok = true; } + private: const BaseType *get_base () const override { return base; } diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc index 1e7c87e..37f93b4 100644 --- a/gcc/rust/typecheck/rust-tyty.cc +++ b/gcc/rust/typecheck/rust-tyty.cc @@ -201,9 +201,10 @@ InferType::unify (BaseType *other) } bool -InferType::can_eq (const BaseType *other, bool emit_errors) const +InferType::can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const { - InferCmp r (this, emit_errors); + InferCmp r (this, emit_errors, autoderef_mode); return r.can_eq (other); } @@ -278,7 +279,8 @@ ErrorType::unify (BaseType *other) } bool -ErrorType::can_eq (const BaseType *other, bool emit_errors) const +ErrorType::can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const { return get_kind () == other->get_kind (); } @@ -641,9 +643,10 @@ ADTType::cast (BaseType *other) } bool -ADTType::can_eq (const BaseType *other, bool emit_errors) const +ADTType::can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const { - ADTCmp r (this, emit_errors); + ADTCmp r (this, emit_errors, autoderef_mode); return r.can_eq (other); } @@ -822,9 +825,10 @@ TupleType::cast (BaseType *other) } bool -TupleType::can_eq (const BaseType *other, bool emit_errors) const +TupleType::can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const { - TupleCmp r (this, emit_errors); + TupleCmp r (this, emit_errors, autoderef_mode); return r.can_eq (other); } @@ -926,9 +930,10 @@ FnType::cast (BaseType *other) } bool -FnType::can_eq (const BaseType *other, bool emit_errors) const +FnType::can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const { - FnCmp r (this, emit_errors); + FnCmp r (this, emit_errors, autoderef_mode); return r.can_eq (other); } @@ -1143,9 +1148,10 @@ FnPtr::cast (BaseType *other) } bool -FnPtr::can_eq (const BaseType *other, bool emit_errors) const +FnPtr::can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const { - FnptrCmp r (this, emit_errors); + FnptrCmp r (this, emit_errors, autoderef_mode); return r.can_eq (other); } @@ -1209,9 +1215,10 @@ ClosureType::unify (BaseType *other) } bool -ClosureType::can_eq (const BaseType *other, bool emit_errors) const +ClosureType::can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const { - ClosureCmp r (this, emit_errors); + ClosureCmp r (this, emit_errors, autoderef_mode); return r.can_eq (other); } @@ -1297,9 +1304,10 @@ ArrayType::cast (BaseType *other) } bool -ArrayType::can_eq (const BaseType *other, bool emit_errors) const +ArrayType::can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const { - ArrayCmp r (this, emit_errors); + ArrayCmp r (this, emit_errors, autoderef_mode); return r.can_eq (other); } @@ -1372,9 +1380,10 @@ BoolType::cast (BaseType *other) } bool -BoolType::can_eq (const BaseType *other, bool emit_errors) const +BoolType::can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const { - BoolCmp r (this, emit_errors); + BoolCmp r (this, emit_errors, autoderef_mode); return r.can_eq (other); } @@ -1438,9 +1447,10 @@ IntType::cast (BaseType *other) } bool -IntType::can_eq (const BaseType *other, bool emit_errors) const +IntType::can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const { - IntCmp r (this, emit_errors); + IntCmp r (this, emit_errors, autoderef_mode); return r.can_eq (other); } @@ -1515,9 +1525,10 @@ UintType::cast (BaseType *other) } bool -UintType::can_eq (const BaseType *other, bool emit_errors) const +UintType::can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const { - UintCmp r (this, emit_errors); + UintCmp r (this, emit_errors, autoderef_mode); return r.can_eq (other); } @@ -1586,9 +1597,10 @@ FloatType::cast (BaseType *other) } bool -FloatType::can_eq (const BaseType *other, bool emit_errors) const +FloatType::can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const { - FloatCmp r (this, emit_errors); + FloatCmp r (this, emit_errors, autoderef_mode); return r.can_eq (other); } @@ -1649,9 +1661,10 @@ USizeType::cast (BaseType *other) } bool -USizeType::can_eq (const BaseType *other, bool emit_errors) const +USizeType::can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const { - USizeCmp r (this, emit_errors); + USizeCmp r (this, emit_errors, autoderef_mode); return r.can_eq (other); } @@ -1701,9 +1714,10 @@ ISizeType::cast (BaseType *other) } bool -ISizeType::can_eq (const BaseType *other, bool emit_errors) const +ISizeType::can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const { - ISizeCmp r (this, emit_errors); + ISizeCmp r (this, emit_errors, autoderef_mode); return r.can_eq (other); } @@ -1753,9 +1767,10 @@ CharType::cast (BaseType *other) } bool -CharType::can_eq (const BaseType *other, bool emit_errors) const +CharType::can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const { - CharCmp r (this, emit_errors); + CharCmp r (this, emit_errors, autoderef_mode); return r.can_eq (other); } @@ -1806,9 +1821,10 @@ ReferenceType::cast (BaseType *other) } bool -ReferenceType::can_eq (const BaseType *other, bool emit_errors) const +ReferenceType::can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const { - ReferenceCmp r (this, emit_errors); + ReferenceCmp r (this, emit_errors, autoderef_mode); return r.can_eq (other); } @@ -1892,9 +1908,10 @@ PointerType::cast (BaseType *other) } bool -PointerType::can_eq (const BaseType *other, bool emit_errors) const +PointerType::can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const { - PointerCmp r (this, emit_errors); + PointerCmp r (this, emit_errors, autoderef_mode); return r.can_eq (other); } @@ -1987,9 +2004,10 @@ ParamType::cast (BaseType *other) } bool -ParamType::can_eq (const BaseType *other, bool emit_errors) const +ParamType::can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const { - ParamCmp r (this, emit_errors); + ParamCmp r (this, emit_errors, autoderef_mode); return r.can_eq (other); } @@ -2044,7 +2062,7 @@ ParamType::is_equal (const BaseType &other) const return false; if (can_resolve ()) - return resolve ()->can_eq (other2.resolve (), false); + return resolve ()->can_eq (other2.resolve (), false, false); return get_symbol ().compare (other2.get_symbol ()) == 0; } @@ -2108,9 +2126,10 @@ StrType::cast (BaseType *other) } bool -StrType::can_eq (const BaseType *other, bool emit_errors) const +StrType::can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const { - StrCmp r (this, emit_errors); + StrCmp r (this, emit_errors, autoderef_mode); return r.can_eq (other); } @@ -2160,9 +2179,10 @@ NeverType::cast (BaseType *other) } bool -NeverType::can_eq (const BaseType *other, bool emit_errors) const +NeverType::can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const { - NeverCmp r (this, emit_errors); + NeverCmp r (this, emit_errors, autoderef_mode); return r.can_eq (other); } @@ -2215,9 +2235,10 @@ PlaceholderType::cast (BaseType *other) } bool -PlaceholderType::can_eq (const BaseType *other, bool emit_errors) const +PlaceholderType::can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const { - PlaceholderCmp r (this, emit_errors); + PlaceholderCmp r (this, emit_errors, autoderef_mode); return r.can_eq (other); } @@ -2315,9 +2336,10 @@ ProjectionType::cast (BaseType *other) } bool -ProjectionType::can_eq (const BaseType *other, bool emit_errors) const +ProjectionType::can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const { - return base->can_eq (other, emit_errors); + return base->can_eq (other, emit_errors, autoderef_mode); } BaseType * @@ -2421,9 +2443,10 @@ DynamicObjectType::unify (BaseType *other) } bool -DynamicObjectType::can_eq (const BaseType *other, bool emit_errors) const +DynamicObjectType::can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const { - DynamicCmp r (this, emit_errors); + DynamicCmp r (this, emit_errors, autoderef_mode); return r.can_eq (other); } diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h index f6a2797..27daa7c 100644 --- a/gcc/rust/typecheck/rust-tyty.h +++ b/gcc/rust/typecheck/rust-tyty.h @@ -259,7 +259,8 @@ public: // // It can also be used to optional emit errors for trait item compatibility // checks - virtual bool can_eq (const BaseType *other, bool emit_errors) const = 0; + virtual bool can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const = 0; // this is the base coercion interface for types virtual BaseType *coerce (BaseType *other) = 0; @@ -404,7 +405,8 @@ public: BaseType *unify (BaseType *other) override; - bool can_eq (const BaseType *other, bool emit_errors) const override final; + bool can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const override final; BaseType *coerce (BaseType *other) override; BaseType *cast (BaseType *other) override; @@ -442,7 +444,8 @@ public: std::string as_string () const override; BaseType *unify (BaseType *other) override; - bool can_eq (const BaseType *other, bool emit_errors) const override final; + bool can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const override final; BaseType *coerce (BaseType *other) override; BaseType *cast (BaseType *other) override; @@ -476,7 +479,8 @@ public: std::string as_string () const override; BaseType *unify (BaseType *other) override; - bool can_eq (const BaseType *other, bool emit_errors) const override final; + bool can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const override final; BaseType *coerce (BaseType *other) override; BaseType *cast (BaseType *other) override; @@ -564,7 +568,8 @@ public: std::string as_string () const override; BaseType *unify (BaseType *other) override; - bool can_eq (const BaseType *other, bool emit_errors) const override final; + bool can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const override final; BaseType *coerce (BaseType *other) override; BaseType *cast (BaseType *other) override; @@ -998,7 +1003,8 @@ public: std::string as_string () const override; BaseType *unify (BaseType *other) override; - bool can_eq (const BaseType *other, bool emit_errors) const override final; + bool can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const override final; BaseType *coerce (BaseType *other) override; BaseType *cast (BaseType *other) override; @@ -1126,7 +1132,8 @@ public: std::string get_identifier () const { return identifier; } BaseType *unify (BaseType *other) override; - bool can_eq (const BaseType *other, bool emit_errors) const override final; + bool can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const override final; BaseType *coerce (BaseType *other) override; BaseType *cast (BaseType *other) override; @@ -1234,7 +1241,8 @@ public: std::string as_string () const override; BaseType *unify (BaseType *other) override; - bool can_eq (const BaseType *other, bool emit_errors) const override final; + bool can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const override final; BaseType *coerce (BaseType *other) override; BaseType *cast (BaseType *other) override; @@ -1294,7 +1302,8 @@ public: 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; + bool can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const override final; BaseType *coerce (BaseType *other) override; BaseType *cast (BaseType *other) override; @@ -1346,7 +1355,8 @@ public: 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; + bool can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const override final; BaseType *coerce (BaseType *other) override; BaseType *cast (BaseType *other) override; @@ -1388,7 +1398,8 @@ public: 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; + bool can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const override final; BaseType *coerce (BaseType *other) override; BaseType *cast (BaseType *other) override; @@ -1424,7 +1435,8 @@ public: 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; + bool can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const override final; BaseType *coerce (BaseType *other) override; BaseType *cast (BaseType *other) override; @@ -1467,7 +1479,8 @@ public: 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; + bool can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const override final; BaseType *coerce (BaseType *other) override; BaseType *cast (BaseType *other) override; @@ -1508,7 +1521,8 @@ public: 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; + bool can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const override final; BaseType *coerce (BaseType *other) override; BaseType *cast (BaseType *other) override; @@ -1541,7 +1555,8 @@ public: 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; + bool can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const override final; BaseType *coerce (BaseType *other) override; BaseType *cast (BaseType *other) override; @@ -1567,7 +1582,8 @@ public: 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; + bool can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const override final; BaseType *coerce (BaseType *other) override; BaseType *cast (BaseType *other) override; @@ -1593,7 +1609,8 @@ public: 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; + bool can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const override final; BaseType *coerce (BaseType *other) override; BaseType *cast (BaseType *other) override; @@ -1623,7 +1640,8 @@ public: 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; + bool can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const override final; BaseType *coerce (BaseType *other) override; BaseType *cast (BaseType *other) override; @@ -1670,7 +1688,8 @@ public: 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; + bool can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const override final; BaseType *coerce (BaseType *other) override; BaseType *cast (BaseType *other) override; @@ -1715,7 +1734,8 @@ public: std::string as_string () const override; BaseType *unify (BaseType *other) override; - bool can_eq (const BaseType *other, bool emit_errors) const override final; + bool can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const override final; BaseType *coerce (BaseType *other) override; BaseType *cast (BaseType *other) override; @@ -1751,7 +1771,8 @@ public: std::string as_string () const override; BaseType *unify (BaseType *other) override; - bool can_eq (const BaseType *other, bool emit_errors) const override final; + bool can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const override final; BaseType *coerce (BaseType *other) override; BaseType *cast (BaseType *other) override; @@ -1784,7 +1805,8 @@ public: std::string as_string () const override; BaseType *unify (BaseType *other) override; - bool can_eq (const BaseType *other, bool emit_errors) const override final; + bool can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const override final; BaseType *coerce (BaseType *other) override; BaseType *cast (BaseType *other) override; @@ -1852,7 +1874,8 @@ public: std::string as_string () const override; BaseType *unify (BaseType *other) override; - bool can_eq (const BaseType *other, bool emit_errors) const override final; + bool can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const override final; BaseType *coerce (BaseType *other) override; BaseType *cast (BaseType *other) override; @@ -1912,7 +1935,8 @@ public: std::string as_string () const override; BaseType *unify (BaseType *other) override; - bool can_eq (const BaseType *other, bool emit_errors) const override final; + bool can_eq (const BaseType *other, bool emit_errors, + bool autoderef_mode) const override final; BaseType *coerce (BaseType *other) override; BaseType *cast (BaseType *other) override; bool is_equal (const BaseType &other) const override; diff --git a/gcc/testsuite/rust/execute/torture/trait8.rs b/gcc/testsuite/rust/execute/torture/trait8.rs new file mode 100644 index 0000000..da8a560 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/trait8.rs @@ -0,0 +1,41 @@ +/* { dg-output "123\n" } */ +extern "C" { + fn printf(s: *const i8, ...); +} + +pub trait Foo { + type A; + + fn bar(&self) -> Self::A; + // { dg-warning "unused name" "" { target *-*-* } .-1 } +} + +struct S(i32); +impl Foo for S { + type A = i32; + + fn bar(&self) -> Self::A { + // { dg-warning "unused name" "" { target *-*-* } .-1 } + self.0 + } +} + +fn test_bar<T: Foo>(x: T) -> T::A { + x.bar() +} + +fn main() -> i32 { + let a; + a = S(123); + + let bar: i32 = test_bar(a); + unsafe { + let a = "%i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, bar); + } + + 0 +} |