Skip to content

Commit c1a0223

Browse files
bors[bot]philberty
andauthored
Merge #1086
1086: Slice support r=philberty a=philberty Please see the commit a8de089 for a long explanation of what's going on in the patch. Unfortunately, I have not been able to split this patch up anymore since supporting slices exposed many bugs in the implementation of generics in general never main the missing support for generic associated types. Fixes #849 Co-authored-by: Philip Herron <[email protected]>
2 parents 6845803 + 0e686c0 commit c1a0223

22 files changed

+833
-307
lines changed

gcc/rust/backend/rust-compile-expr.cc

+15-4
Original file line numberDiff line numberDiff line change
@@ -747,8 +747,9 @@ CompileExpr::resolve_method_address (TyTy::FnType *fntype, HirId ref,
747747

748748
auto root = receiver->get_root ();
749749
std::vector<Resolver::PathProbeCandidate> candidates
750-
= Resolver::PathProbeType::Probe (root, segment, true, false, true);
751-
750+
= Resolver::PathProbeType::Probe (root, segment, true /* probe_impls */,
751+
false /* probe_bounds */,
752+
true /* ignore_mandatory_trait_items */);
752753
if (candidates.size () == 0)
753754
{
754755
// this means we are defaulting back to the trait_item if
@@ -776,12 +777,22 @@ CompileExpr::resolve_method_address (TyTy::FnType *fntype, HirId ref,
776777
rust_assert (candidates.size () == 1);
777778
auto &candidate = candidates.at (0);
778779
rust_assert (candidate.is_impl_candidate ());
780+
rust_assert (candidate.ty->get_kind () == TyTy::TypeKind::FNDEF);
781+
TyTy::FnType *candidate_call = static_cast<TyTy::FnType *> (candidate.ty);
779782

780783
HIR::ImplItem *impl_item = candidate.item.impl.impl_item;
781-
if (!fntype->has_subsititions_defined ())
784+
if (!candidate_call->has_subsititions_defined ())
782785
return CompileInherentImplItem::Compile (impl_item, ctx);
783786

784-
return CompileInherentImplItem::Compile (impl_item, ctx, fntype);
787+
TyTy::BaseType *monomorphized = candidate_call;
788+
if (candidate_call->needs_generic_substitutions ())
789+
{
790+
TyTy::BaseType *infer_impl_call
791+
= candidate_call->infer_substitions (expr_locus);
792+
monomorphized = infer_impl_call->unify (fntype);
793+
}
794+
795+
return CompileInherentImplItem::Compile (impl_item, ctx, monomorphized);
785796
}
786797
}
787798

gcc/rust/backend/rust-compile.cc

+1-17
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ CompileCrate::~CompileCrate () {}
3838

3939
void
4040
CompileCrate::Compile (HIR::Crate &crate, Context *ctx)
41-
4241
{
4342
CompileCrate c (crate, ctx);
4443
c.go ();
@@ -383,26 +382,11 @@ HIRCompileBase::compute_address_for_trait_item (
383382
= self_bound->lookup_associated_item (ref->get_identifier ());
384383
rust_assert (!associated_self_item.is_error ());
385384

386-
// apply any generic arguments from this predicate
387385
TyTy::BaseType *mono1 = associated_self_item.get_tyty_for_receiver (self);
388-
TyTy::BaseType *mono2 = nullptr;
389-
if (predicate->has_generic_args ())
390-
{
391-
mono2 = associated_self_item.get_tyty_for_receiver (
392-
self, predicate->get_generic_args ());
393-
}
394-
else
395-
{
396-
mono2 = associated_self_item.get_tyty_for_receiver (self);
397-
}
398386
rust_assert (mono1 != nullptr);
399387
rust_assert (mono1->get_kind () == TyTy::TypeKind::FNDEF);
400388
TyTy::FnType *assocated_item_ty1 = static_cast<TyTy::FnType *> (mono1);
401389

402-
rust_assert (mono2 != nullptr);
403-
rust_assert (mono2->get_kind () == TyTy::TypeKind::FNDEF);
404-
TyTy::FnType *assocated_item_ty2 = static_cast<TyTy::FnType *> (mono2);
405-
406390
// Lookup the impl-block for the associated impl_item if it exists
407391
HIR::Function *associated_function = nullptr;
408392
for (auto &impl_item : associated_impl_block->get_impl_items ())
@@ -434,7 +418,7 @@ HIRCompileBase::compute_address_for_trait_item (
434418
{
435419
TyTy::SubstitutionArgumentMappings mappings
436420
= assocated_item_ty1->solve_missing_mappings_from_this (
437-
*assocated_item_ty2, *lookup_fntype);
421+
*trait_item_fntype, *lookup_fntype);
438422
lookup_fntype = lookup_fntype->handle_substitions (mappings);
439423
}
440424

gcc/rust/typecheck/rust-hir-dot-operator.cc

+33-31
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,11 @@ MethodResolver::Try (const TyTy::BaseType *r,
126126
PathProbeCandidate c = PathProbeCandidate::get_error ();
127127
const std::vector<TyTy::TypeBoundPredicate> &specified_bounds
128128
= r->get_specified_bounds ();
129+
const std::vector<MethodResolver::predicate_candidate> predicate_items
130+
= get_predicate_items (segment_name, *r, specified_bounds);
129131

130132
// 1. try raw
131-
MethodResolver raw (*r, segment_name, specified_bounds);
133+
MethodResolver raw (*r, segment_name, predicate_items);
132134
c = raw.select ();
133135
if (!c.is_error ())
134136
{
@@ -139,7 +141,7 @@ MethodResolver::Try (const TyTy::BaseType *r,
139141
TyTy::ReferenceType *r1
140142
= new TyTy::ReferenceType (r->get_ref (), TyTy::TyVar (r->get_ref ()),
141143
Mutability::Imm);
142-
MethodResolver imm_ref (*r1, segment_name, specified_bounds);
144+
MethodResolver imm_ref (*r1, segment_name, predicate_items);
143145
c = imm_ref.select ();
144146
if (!c.is_error ())
145147
{
@@ -152,7 +154,7 @@ MethodResolver::Try (const TyTy::BaseType *r,
152154
TyTy::ReferenceType *r2
153155
= new TyTy::ReferenceType (r->get_ref (), TyTy::TyVar (r->get_ref ()),
154156
Mutability::Mut);
155-
MethodResolver mut_ref (*r2, segment_name, specified_bounds);
157+
MethodResolver mut_ref (*r2, segment_name, predicate_items);
156158
c = mut_ref.select ();
157159
if (!c.is_error ())
158160
{
@@ -288,27 +290,6 @@ MethodResolver::select ()
288290
TyTy::FnType *fntype;
289291
};
290292

291-
std::vector<precdicate_candidate> predicate_items;
292-
for (auto &bound : specified_bounds)
293-
{
294-
TyTy::TypeBoundPredicateItem lookup
295-
= bound.lookup_associated_item (segment_name.as_string ());
296-
if (lookup.is_error ())
297-
continue;
298-
299-
bool is_fn = lookup.get_raw_item ()->get_trait_item_type ()
300-
== TraitItemReference::TraitItemType::FN;
301-
if (!is_fn)
302-
continue;
303-
304-
TyTy::BaseType *ty = lookup.get_raw_item ()->get_tyty ();
305-
rust_assert (ty->get_kind () == TyTy::TypeKind::FNDEF);
306-
TyTy::FnType *fnty = static_cast<TyTy::FnType *> (ty);
307-
308-
precdicate_candidate candidate{lookup, fnty};
309-
predicate_items.push_back (candidate);
310-
}
311-
312293
for (auto impl_item : inherent_impl_fns)
313294
{
314295
TyTy::FnType *fn = impl_item.ty;
@@ -342,9 +323,9 @@ MethodResolver::select ()
342323
}
343324
}
344325

345-
for (auto predicate : predicate_items)
326+
for (const auto &predicate : predicate_items)
346327
{
347-
TyTy::FnType *fn = predicate.fntype;
328+
const TyTy::FnType *fn = predicate.fntype;
348329
rust_assert (fn->is_method ());
349330

350331
TyTy::BaseType *fn_self = fn->get_self_type ();
@@ -355,20 +336,41 @@ MethodResolver::select ()
355336
const TraitItemReference *trait_item
356337
= predicate.lookup.get_raw_item ();
357338

358-
TyTy::BaseType *subst = predicate.lookup.get_tyty_for_receiver (
359-
receiver.get_root (),
360-
predicate.lookup.get_parent ()->get_generic_args ());
361-
362339
PathProbeCandidate::TraitItemCandidate c{trait_ref, trait_item,
363340
nullptr};
364341
return PathProbeCandidate (
365-
PathProbeCandidate::CandidateType::TRAIT_FUNC, subst,
342+
PathProbeCandidate::CandidateType::TRAIT_FUNC, fn->clone (),
366343
trait_item->get_locus (), c);
367344
}
368345
}
369346

370347
return PathProbeCandidate::get_error ();
371348
}
372349

350+
std::vector<MethodResolver::predicate_candidate>
351+
MethodResolver::get_predicate_items (
352+
const HIR::PathIdentSegment &segment_name, const TyTy::BaseType &receiver,
353+
const std::vector<TyTy::TypeBoundPredicate> &specified_bounds)
354+
{
355+
std::vector<predicate_candidate> predicate_items;
356+
for (auto &bound : specified_bounds)
357+
{
358+
TyTy::TypeBoundPredicateItem lookup
359+
= bound.lookup_associated_item (segment_name.as_string ());
360+
if (lookup.is_error ())
361+
continue;
362+
363+
TyTy::BaseType *ty = lookup.get_tyty_for_receiver (&receiver);
364+
if (ty->get_kind () == TyTy::TypeKind::FNDEF)
365+
{
366+
TyTy::FnType *fnty = static_cast<TyTy::FnType *> (ty);
367+
predicate_candidate candidate{lookup, fnty};
368+
predicate_items.push_back (candidate);
369+
}
370+
}
371+
372+
return predicate_items;
373+
}
374+
373375
} // namespace Resolver
374376
} // namespace Rust

gcc/rust/typecheck/rust-hir-dot-operator.h

+15-5
Original file line numberDiff line numberDiff line change
@@ -48,22 +48,32 @@ class MethodResolver : public TypeCheckBase
4848
bool autoderef_flag = false);
4949

5050
protected:
51+
struct predicate_candidate
52+
{
53+
TyTy::TypeBoundPredicateItem lookup;
54+
TyTy::FnType *fntype;
55+
};
56+
5157
static MethodCandidate Try (const TyTy::BaseType *r,
5258
const HIR::PathIdentSegment &segment_name,
5359
std::vector<Adjustment> &adjustments);
5460

61+
static std::vector<predicate_candidate> get_predicate_items (
62+
const HIR::PathIdentSegment &segment_name, const TyTy::BaseType &receiver,
63+
const std::vector<TyTy::TypeBoundPredicate> &specified_bounds);
64+
5565
PathProbeCandidate select ();
5666

57-
MethodResolver (const TyTy::BaseType &receiver,
58-
const HIR::PathIdentSegment &segment_name,
59-
const std::vector<TyTy::TypeBoundPredicate> &specified_bounds)
67+
MethodResolver (
68+
const TyTy::BaseType &receiver, const HIR::PathIdentSegment &segment_name,
69+
const std::vector<MethodResolver::predicate_candidate> &predicate_items)
6070
: receiver (receiver), segment_name (segment_name),
61-
specified_bounds (specified_bounds)
71+
predicate_items (predicate_items)
6272
{}
6373

6474
const TyTy::BaseType &receiver;
6575
const HIR::PathIdentSegment &segment_name;
66-
const std::vector<TyTy::TypeBoundPredicate> &specified_bounds;
76+
const std::vector<MethodResolver::predicate_candidate> &predicate_items;
6777
};
6878

6979
} // namespace Resolver

gcc/rust/typecheck/rust-hir-trait-ref.h

+5
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,8 @@ class TraitReference
262262
return hir_trait_ref->get_mappings ();
263263
}
264264

265+
DefId get_defid () const { return get_mappings ().get_defid (); }
266+
265267
bool lookup_hir_trait_item (const HIR::TraitItem &item,
266268
TraitItemReference **ref)
267269
{
@@ -436,6 +438,9 @@ class AssociatedImplTrait
436438

437439
void setup_associated_types ();
438440

441+
void setup_associated_types2 (const TyTy::BaseType *self,
442+
const TyTy::TypeBoundPredicate &bound);
443+
439444
void reset_associated_types ();
440445

441446
TyTy::BaseType *get_projected_type (const TraitItemReference *trait_item_ref,

0 commit comments

Comments
 (0)