public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] Ensure autoderef for generic recivers in method calls
@ 2022-06-08 11:42 Thomas Schwinge
0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2022-06-08 11:42 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:243e5d800dc03f36025e72d275b79a2098dbb953
commit 243e5d800dc03f36025e72d275b79a2098dbb953
Author: Philip Herron <philip.herron@embecosm.com>
Date: Wed Oct 20 19:39:01 2021 +0100
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
Diff:
---
gcc/rust/typecheck/rust-hir-dot-operator.h | 6 +-
.../typecheck/rust-hir-inherent-impl-overlap.h | 2 +-
gcc/rust/typecheck/rust-hir-path-probe.h | 2 +-
gcc/rust/typecheck/rust-hir-type-check-expr.h | 2 +-
gcc/rust/typecheck/rust-hir-type-check-implitem.h | 6 +-
gcc/rust/typecheck/rust-hir-type-check-path.cc | 7 +-
gcc/rust/typecheck/rust-hir-type-check.h | 2 +-
gcc/rust/typecheck/rust-tyty-bounds.cc | 2 +-
gcc/rust/typecheck/rust-tyty-cmp.h | 227 ++++++++++++++-------
gcc/rust/typecheck/rust-tyty.cc | 115 ++++++-----
gcc/rust/typecheck/rust-tyty.h | 72 ++++---
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 9c0cc431c2a..98ae5ab65d9 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 9a2c7fe3c07..eac86b01cdc 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 d2b5f5b5c78..8ceec00ffce 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 83fafa66ee5..8c415ebd446 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 1260c2e7c88..f3a08707dfd 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 0aea8ca669a..c74ac85ae7e 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 d3dc4c997c0..5760c4e9c5d 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 5f69deb52d3..89093949e41 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 519501fa02c..9ebd5647cc1 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 1e7c87e0beb..37f93b40cf4 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 f6a279737d1..27daa7cf57d 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 00000000000..da8a560388e
--- /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
+}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-06-08 11:42 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-08 11:42 [gcc/devel/rust/master] Ensure autoderef for generic recivers in method calls Thomas Schwinge
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).