aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/backend/rust-compile-expr.cc4
-rw-r--r--gcc/rust/backend/rust-compile-resolve-path.cc8
-rw-r--r--gcc/rust/typecheck/rust-hir-path-probe.h108
-rw-r--r--gcc/rust/typecheck/rust-hir-trait-ref.h19
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-enumitem.cc4
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-item.cc9
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-path.cc2
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-type.cc2
-rw-r--r--gcc/rust/typecheck/rust-tyty.h22
-rw-r--r--gcc/testsuite/rust/compile/torture/issue-1555.rs48
10 files changed, 147 insertions, 79 deletions
diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc
index 660ad09..9ff2be6 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -1982,7 +1982,7 @@ CompileExpr::resolve_method_address (TyTy::FnType *fntype, HirId ref,
// trait-impl-item's definition
auto root = receiver->get_root ();
- std::vector<Resolver::PathProbeCandidate> candidates
+ auto candidates
= Resolver::PathProbeType::Probe (root, segment, true /* probe_impls */,
false /* probe_bounds */,
true /* ignore_mandatory_trait_items */);
@@ -2011,7 +2011,7 @@ CompileExpr::resolve_method_address (TyTy::FnType *fntype, HirId ref,
// implementation and we should just return error_mark_node
rust_assert (candidates.size () == 1);
- auto &candidate = candidates.at (0);
+ auto &candidate = *candidates.begin ();
rust_assert (candidate.is_impl_candidate ());
rust_assert (candidate.ty->get_kind () == TyTy::TypeKind::FNDEF);
TyTy::FnType *candidate_call = static_cast<TyTy::FnType *> (candidate.ty);
diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc
index 4fb3d54..f89da2b 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -251,7 +251,7 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup,
// item so its up to us to figure out if this path should resolve
// to an trait-impl-block-item or if it can be defaulted to the
// trait-impl-item's definition
- std::vector<Resolver::PathProbeCandidate> candidates
+ auto candidates
= Resolver::PathProbeImplTrait::Probe (receiver, final_segment,
trait_ref);
if (candidates.size () == 0)
@@ -270,7 +270,9 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup,
}
else
{
- Resolver::PathProbeCandidate &candidate = candidates.at (0);
+ rust_assert (candidates.size () == 1);
+
+ auto candidate = *candidates.begin ();
rust_assert (candidate.is_impl_candidate ());
HIR::ImplBlock *impl = candidate.item.impl.parent;
@@ -288,8 +290,6 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup,
else
return CompileInherentImplItem::Compile (impl_item, ctx, lookup,
true, expr_locus);
-
- lookup->set_ty_ref (impl_item->get_impl_mappings ().get_hirid ());
}
}
}
diff --git a/gcc/rust/typecheck/rust-hir-path-probe.h b/gcc/rust/typecheck/rust-hir-path-probe.h
index b1d7f4b..c8f207c 100644
--- a/gcc/rust/typecheck/rust-hir-path-probe.h
+++ b/gcc/rust/typecheck/rust-hir-path-probe.h
@@ -80,17 +80,17 @@ struct PathProbeCandidate
PathProbeCandidate (CandidateType type, TyTy::BaseType *ty, Location locus,
EnumItemCandidate enum_field)
- : type (type), ty (ty), item (enum_field)
+ : type (type), ty (ty), locus (locus), item (enum_field)
{}
PathProbeCandidate (CandidateType type, TyTy::BaseType *ty, Location locus,
ImplItemCandidate impl)
- : type (type), ty (ty), item (impl)
+ : type (type), ty (ty), locus (locus), item (impl)
{}
PathProbeCandidate (CandidateType type, TyTy::BaseType *ty, Location locus,
TraitItemCandidate trait)
- : type (type), ty (ty), item (trait)
+ : type (type), ty (ty), locus (locus), item (trait)
{}
std::string as_string () const
@@ -123,12 +123,45 @@ struct PathProbeCandidate
}
bool is_error () const { return type == ERROR; }
+
+ DefId get_defid () const
+ {
+ switch (type)
+ {
+ case ENUM_VARIANT:
+ return item.enum_field.variant->get_defid ();
+ break;
+
+ case IMPL_CONST:
+ case IMPL_TYPE_ALIAS:
+ case IMPL_FUNC:
+ return item.impl.impl_item->get_impl_mappings ().get_defid ();
+ break;
+
+ case TRAIT_ITEM_CONST:
+ case TRAIT_TYPE_ALIAS:
+ case TRAIT_FUNC:
+ return item.trait.item_ref->get_mappings ().get_defid ();
+ break;
+
+ case ERROR:
+ default:
+ return UNKNOWN_DEFID;
+ }
+
+ return UNKNOWN_DEFID;
+ }
+
+ bool operator< (const PathProbeCandidate &c) const
+ {
+ return get_defid () < c.get_defid ();
+ }
};
class PathProbeType : public TypeCheckBase, public HIR::HIRImplVisitor
{
public:
- static std::vector<PathProbeCandidate>
+ static std::set<PathProbeCandidate>
Probe (const TyTy::BaseType *receiver,
const HIR::PathIdentSegment &segment_name, bool probe_impls,
bool probe_bounds, bool ignore_mandatory_trait_items,
@@ -203,7 +236,7 @@ public:
PathProbeCandidate candidate{
PathProbeCandidate::CandidateType::IMPL_TYPE_ALIAS, ty,
alias.get_locus (), impl_item_candidate};
- candidates.push_back (std::move (candidate));
+ candidates.insert (std::move (candidate));
}
}
@@ -222,7 +255,7 @@ public:
PathProbeCandidate candidate{
PathProbeCandidate::CandidateType::IMPL_CONST, ty,
constant.get_locus (), impl_item_candidate};
- candidates.push_back (std::move (candidate));
+ candidates.insert (std::move (candidate));
}
}
@@ -241,7 +274,7 @@ public:
PathProbeCandidate candidate{
PathProbeCandidate::CandidateType::IMPL_FUNC, ty,
function.get_locus (), impl_item_candidate};
- candidates.push_back (std::move (candidate));
+ candidates.insert (std::move (candidate));
}
}
@@ -259,7 +292,7 @@ protected:
PathProbeCandidate candidate{
PathProbeCandidate::CandidateType::ENUM_VARIANT, receiver->clone (),
mappings->lookup_location (adt->get_ty_ref ()), enum_item_candidate};
- candidates.push_back (std::move (candidate));
+ candidates.insert (std::move (candidate));
}
void process_impl_items_for_candidates ()
@@ -338,8 +371,9 @@ protected:
impl};
PathProbeCandidate candidate{candidate_type, trait_item_tyty,
- trait_ref->get_locus (), trait_item_candidate};
- candidates.push_back (std::move (candidate));
+ trait_item_ref->get_locus (),
+ trait_item_candidate};
+ candidates.insert (std::move (candidate));
}
void
@@ -383,7 +417,7 @@ protected:
PathProbeCandidate candidate{candidate_type, trait_item_tyty,
trait_item_ref->get_locus (),
trait_item_candidate};
- candidates.push_back (std::move (candidate));
+ candidates.insert (std::move (candidate));
}
protected:
@@ -428,72 +462,30 @@ protected:
const TyTy::BaseType *receiver;
const HIR::PathIdentSegment &search;
- std::vector<PathProbeCandidate> candidates;
+ std::set<PathProbeCandidate> candidates;
HIR::ImplBlock *current_impl;
DefId specific_trait_id;
};
-class ReportMultipleCandidateError : private TypeCheckBase,
- private HIR::HIRImplVisitor
+class ReportMultipleCandidateError : private TypeCheckBase
{
public:
- static void Report (std::vector<PathProbeCandidate> &candidates,
+ static void Report (std::set<PathProbeCandidate> &candidates,
const HIR::PathIdentSegment &query, Location query_locus)
{
RichLocation r (query_locus);
- ReportMultipleCandidateError visitor (r);
for (auto &c : candidates)
- {
- switch (c.type)
- {
- case PathProbeCandidate::CandidateType::ERROR:
- case PathProbeCandidate::CandidateType::ENUM_VARIANT:
- gcc_unreachable ();
- break;
-
- case PathProbeCandidate::CandidateType::IMPL_CONST:
- case PathProbeCandidate::CandidateType::IMPL_TYPE_ALIAS:
- case PathProbeCandidate::CandidateType::IMPL_FUNC:
- c.item.impl.impl_item->accept_vis (visitor);
- break;
-
- case PathProbeCandidate::CandidateType::TRAIT_ITEM_CONST:
- case PathProbeCandidate::CandidateType::TRAIT_TYPE_ALIAS:
- case PathProbeCandidate::CandidateType::TRAIT_FUNC:
- r.add_range (c.item.trait.item_ref->get_locus ());
- break;
- }
- }
+ r.add_range (c.locus);
rust_error_at (r, "multiple applicable items in scope for: %s",
query.as_string ().c_str ());
}
-
- void visit (HIR::TypeAlias &alias) override
- {
- r.add_range (alias.get_locus ());
- }
-
- void visit (HIR::ConstantItem &constant) override
- {
- r.add_range (constant.get_locus ());
- }
-
- void visit (HIR::Function &function) override
- {
- r.add_range (function.get_locus ());
- }
-
-private:
- ReportMultipleCandidateError (RichLocation &r) : TypeCheckBase (), r (r) {}
-
- RichLocation &r;
};
class PathProbeImplTrait : public PathProbeType
{
public:
- static std::vector<PathProbeCandidate>
+ static std::set<PathProbeCandidate>
Probe (const TyTy::BaseType *receiver,
const HIR::PathIdentSegment &segment_name,
const TraitReference *trait_reference)
diff --git a/gcc/rust/typecheck/rust-hir-trait-ref.h b/gcc/rust/typecheck/rust-hir-trait-ref.h
index 6eec461..0f4883d 100644
--- a/gcc/rust/typecheck/rust-hir-trait-ref.h
+++ b/gcc/rust/typecheck/rust-hir-trait-ref.h
@@ -336,6 +336,15 @@ public:
return true;
}
}
+
+ // lookup super traits
+ for (const auto &super_trait : super_traits)
+ {
+ bool found = super_trait->lookup_trait_item (ident, ref);
+ if (found)
+ return true;
+ }
+
return false;
}
@@ -351,6 +360,16 @@ public:
if (ident.compare (item.get_identifier ()) == 0)
return &item;
}
+
+ // lookup super traits
+ for (const auto &super_trait : super_traits)
+ {
+ const TraitItemReference *res
+ = super_trait->lookup_trait_item (ident, type);
+ if (!res->is_error ())
+ return res;
+ }
+
return &TraitItemReference::error_node ();
}
diff --git a/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc b/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc
index 59b58a2..b695ced 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc
@@ -82,6 +82,7 @@ TypeCheckEnumItem::visit (HIR::EnumItem &item)
RustIdent ident{*canonical_path, item.get_locus ()};
variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
+ item.get_mappings ().get_defid (),
item.get_identifier (), ident, discim_expr);
}
@@ -111,6 +112,7 @@ TypeCheckEnumItem::visit (HIR::EnumItemDiscriminant &item)
RustIdent ident{*canonical_path, item.get_locus ()};
variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
+ item.get_mappings ().get_defid (),
item.get_identifier (), ident,
item.get_discriminant_expression ().get ());
}
@@ -159,6 +161,7 @@ TypeCheckEnumItem::visit (HIR::EnumItemTuple &item)
RustIdent ident{*canonical_path, item.get_locus ()};
variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
+ item.get_mappings ().get_defid (),
item.get_identifier (), ident,
TyTy::VariantDef::VariantType::TUPLE,
discim_expr, fields);
@@ -206,6 +209,7 @@ TypeCheckEnumItem::visit (HIR::EnumItemStruct &item)
RustIdent ident{*canonical_path, item.get_locus ()};
variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
+ item.get_mappings ().get_defid (),
item.get_identifier (), ident,
TyTy::VariantDef::VariantType::STRUCT,
discrim_expr, fields);
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc b/gcc/rust/typecheck/rust-hir-type-check-item.cc
index ade6ab7..de994e6 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.cc
@@ -125,7 +125,8 @@ TypeCheckItem::visit (HIR::TupleStruct &struct_decl)
// its a single variant ADT
std::vector<TyTy::VariantDef *> variants;
variants.push_back (new TyTy::VariantDef (
- struct_decl.get_mappings ().get_hirid (), struct_decl.get_identifier (),
+ struct_decl.get_mappings ().get_hirid (),
+ struct_decl.get_mappings ().get_defid (), struct_decl.get_identifier (),
ident, TyTy::VariantDef::VariantType::TUPLE, nullptr, std::move (fields)));
// Process #[repr(X)] attribute, if any
@@ -179,7 +180,8 @@ TypeCheckItem::visit (HIR::StructStruct &struct_decl)
// its a single variant ADT
std::vector<TyTy::VariantDef *> variants;
variants.push_back (new TyTy::VariantDef (
- struct_decl.get_mappings ().get_hirid (), struct_decl.get_identifier (),
+ struct_decl.get_mappings ().get_hirid (),
+ struct_decl.get_mappings ().get_defid (), struct_decl.get_identifier (),
ident, TyTy::VariantDef::VariantType::STRUCT, nullptr, std::move (fields)));
// Process #[repr(X)] attribute, if any
@@ -273,7 +275,8 @@ TypeCheckItem::visit (HIR::Union &union_decl)
// there is only a single variant
std::vector<TyTy::VariantDef *> variants;
variants.push_back (new TyTy::VariantDef (
- union_decl.get_mappings ().get_hirid (), union_decl.get_identifier (),
+ union_decl.get_mappings ().get_hirid (),
+ union_decl.get_mappings ().get_defid (), union_decl.get_identifier (),
ident, TyTy::VariantDef::VariantType::STRUCT, nullptr, std::move (fields)));
TyTy::BaseType *type
diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index 2450576..4e765ad 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -337,7 +337,7 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id,
return;
}
- auto &candidate = candidates.at (0);
+ auto &candidate = *candidates.begin ();
prev_segment = tyseg;
tyseg = candidate.ty;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index a47d40e..67e6cb0e 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -462,7 +462,7 @@ TypeCheckType::resolve_segments (
return new TyTy::ErrorType (expr_id);
}
- auto &candidate = candidates.at (0);
+ auto &candidate = *candidates.begin ();
prev_segment = tyseg;
tyseg = candidate.ty;
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index cad1a1d..acbeb9c 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -1063,9 +1063,9 @@ public:
return "";
}
- VariantDef (HirId id, std::string identifier, RustIdent ident,
+ VariantDef (HirId id, DefId defid, std::string identifier, RustIdent ident,
HIR::Expr *discriminant)
- : id (id), identifier (identifier), ident (ident),
+ : id (id), defid (defid), identifier (identifier), ident (ident),
discriminant (discriminant)
{
@@ -1073,11 +1073,11 @@ public:
fields = {};
}
- VariantDef (HirId id, std::string identifier, RustIdent ident,
+ VariantDef (HirId id, DefId defid, std::string identifier, RustIdent ident,
VariantType type, HIR::Expr *discriminant,
std::vector<StructFieldType *> fields)
- : id (id), identifier (identifier), ident (ident), type (type),
- discriminant (discriminant), fields (fields)
+ : id (id), defid (defid), identifier (identifier), ident (ident),
+ type (type), discriminant (discriminant), fields (fields)
{
rust_assert (
(type == VariantType::NUM && fields.empty ())
@@ -1085,8 +1085,8 @@ public:
}
VariantDef (const VariantDef &other)
- : id (other.id), identifier (other.identifier), ident (other.ident),
- type (other.type), discriminant (other.discriminant),
+ : id (other.id), defid (other.defid), identifier (other.identifier),
+ ident (other.ident), type (other.type), discriminant (other.discriminant),
fields (other.fields)
{}
@@ -1105,7 +1105,7 @@ public:
static VariantDef &get_error_node ()
{
static VariantDef node
- = VariantDef (UNKNOWN_HIRID, "",
+ = VariantDef (UNKNOWN_HIRID, UNKNOWN_DEFID, "",
{Resolver::CanonicalPath::create_empty (),
Linemap::unknown_location ()},
nullptr);
@@ -1116,6 +1116,7 @@ public:
bool is_error () const { return get_id () == UNKNOWN_HIRID; }
HirId get_id () const { return id; }
+ DefId get_defid () const { return defid; }
VariantType get_variant_type () const { return type; }
bool is_data_variant () const { return type != VariantType::NUM; }
@@ -1211,7 +1212,7 @@ public:
for (auto &f : fields)
cloned_fields.push_back ((StructFieldType *) f->clone ());
- return new VariantDef (id, identifier, ident, type, discriminant,
+ return new VariantDef (id, defid, identifier, ident, type, discriminant,
cloned_fields);
}
@@ -1221,7 +1222,7 @@ public:
for (auto &f : fields)
cloned_fields.push_back ((StructFieldType *) f->monomorphized_clone ());
- return new VariantDef (id, identifier, ident, type, discriminant,
+ return new VariantDef (id, defid, identifier, ident, type, discriminant,
cloned_fields);
}
@@ -1229,6 +1230,7 @@ public:
private:
HirId id;
+ DefId defid;
std::string identifier;
RustIdent ident;
VariantType type;
diff --git a/gcc/testsuite/rust/compile/torture/issue-1555.rs b/gcc/testsuite/rust/compile/torture/issue-1555.rs
new file mode 100644
index 0000000..adb4891
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/issue-1555.rs
@@ -0,0 +1,48 @@
+extern "C" {
+ fn printf(s: *const i8, ...);
+}
+
+struct Foo(i32);
+trait Bar {
+ fn baz(&self);
+}
+
+trait Baz: Bar {
+ fn qux(&self);
+}
+
+impl Bar for Foo {
+ fn baz(&self) {
+ unsafe {
+ let a = "baz %i\n\0";
+ let b = a as *const str;
+ let c = b as *const i8;
+
+ printf(c, self.0);
+ }
+ }
+}
+
+impl Baz for Foo {
+ fn qux(&self) {
+ unsafe {
+ let a = "qux %i\n\0";
+ let b = a as *const str;
+ let c = b as *const i8;
+
+ printf(c, self.0);
+ }
+ }
+}
+
+fn static_dispatch<T: Baz>(t: &T) {
+ t.baz();
+ t.qux();
+}
+
+pub fn main() {
+ let a;
+ a = &Foo(123);
+
+ static_dispatch(a);
+}